package game.module.qzmj.logic;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import db.proto.ProtoMessageQzmj.ARound;
import db.proto.ProtoMessageQzmj.AllAction;
import db.proto.ProtoMessageQzmj.AllPlayers;
import db.proto.ProtoMessageQzmj.AllRound;
import db.proto.ProtoMessageQzmj.ByteArray;
import db.proto.Protoname.Battlename;
import db.proto.Protoname.Player;
//import ch.qos.logback.classic.pattern.Util;
//import db.proto.ProtoMessageQzmj;
//import db.proto.ProtoMessageQzmj.AllRound;
import game.RoomServer;
import game.entity.PlayingRole;
import game.lan.msg.QzmjStar2HsMessage;
import game.module.RoomType;
import game.module.battlereport.bean.BattleReport;
import game.module.battlereport.bean.PlayerReport;
import game.module.battlereport.dao.BattleReportDBHelper;
import game.module.battlereport.dao.PlayerReportDBHelper;
import game.module.battlereport.logic.BattleReportManager;
import game.module.qzmj.QzmjConstants;
import game.module.qzmj.bean.CChiHuRight;
import game.module.qzmj.bean.QzmjLanPlayerInfo;
import game.module.qzmj.bean.QzmjRound;
import game.module.qzmj.bean.TagAnalyseItem;
import game.module.qzmj.bean.TagGangCardResult;
import game.module.qzmj.bean.TagKindItem;
import game.module.qzmj.bean.TagWeaveItem;
import game.module.user.bean.PlayerBean;
import game.module.user.dao.LanSessionCache;
import game.module.user.logic.RoomDataManager;
import game.session.SessionManager;
import io.netty.channel.Channel;
import lion.common.ArrayUtility;
import lua.LuaMessageQzmj.AnalyseItem;
import lua.LuaMessageQzmj.CbCardData;
import lua.LuaMessageQzmj.PushQzmjBuHua;
import lua.LuaMessageQzmj.PushQzmjGameOver;
import lua.LuaMessageQzmj.PushQzmjJinState;
import lua.LuaMessageQzmj.PushQzmjMopai;
import lua.LuaMessageQzmj.PushQzmjRoundOver;
import lua.LuaMessageQzmj.PushQzmjUserAction;
import lua.LuaMessageQzmj.PushQzmjYaoshaizi;
import lua.LuaMessageQzmj.QzmjHuaPai;
import lua.LuaMessageQzmj.QzmjPlayerCard;

public class QzmjLogic {

	private static Logger logger = LoggerFactory.getLogger(QzmjLogic.class);

	static class SingletonHolder {
		static QzmjLogic instance = new QzmjLogic();
	}

	public static QzmjLogic getInstance() {
		return SingletonHolder.instance;
	}

	public void GameStart(QzmjRound mjRound) {
		if (mjRound.isGamestart())
			return;
		mjRound.setGamestart(true);
		ARound.Builder around = ARound.newBuilder();
		//ByteArray.Builder dice = ByteArray.newBuilder();
		
		List<Short> shaizi = new ArrayList<>();// 存放色子的数组
		List<Byte> god = new ArrayList<>(); // 存放翻金牌的牌
		shaizi.add((short) RandomUtils.nextInt(1, 7));
		shaizi.add((short) RandomUtils.nextInt(1, 7));
		around.addDice(shaizi.get(0));
		around.addDice(shaizi.get(1));
		around.setRoundcount(mjRound.getRound_count()-mjRound.getRoundSum()+
				1);
		around.setCreatetime((int)(System.currentTimeMillis()/1000));
		byte[][] cards = mjRound.getCards();
		int zhuangjia_index = mjRound.getM_wBankerUser();
		byte[] zhuangjia_cards = cards[zhuangjia_index];
        
		List<Byte> remainCards = mjRound.getRemain_card();
		zhuangjia_cards[16] = remainCards.get(0); // 庄家跳牌
		// --------------------------------------------------------测试
		remainCards.remove(0);
		byte Bankuser_card = zhuangjia_cards[16];
		mjRound.setM_wProvideUser(zhuangjia_index);
		List<List<Byte>> huapais = new ArrayList<>();
		List<List<Byte>> filled_cards = new ArrayList<>();
		QzmjHuaPai[] mjhuapai = new QzmjHuaPai[4];
		int i = 0;
		byte buhua_count = 0;
		for (byte[] card : cards) {
		//	logger.info("mj chu shi card={}", card);
			List<Byte> huapai = new ArrayList<>();
			List<Byte> aplayfilledcard = new ArrayList<>();
			int huapaiCount = 0;
			// 找出花牌
			ByteArray.Builder fistcard = ByteArray.newBuilder();
			for (int j = 0; j < card.length; j++) {
				fistcard.addAByte(card[j]);
				if (card[j] > 55) {
					huapai.add(card[j]);
					card[j] = 0;
					huapaiCount++;

				}
			}
			ByteArray realfistcard = fistcard.build();
			around.addHandsCard(realfistcard);
			
			buhua_count += huapaiCount;
			int index = card.length - 1;
			for (int m = 0; m < card.length - 1; m++) {
				if (card[m] == 0) {
					while (card[index] == 0) {
						index--;
					}
					if (index <= m)
						break;
					card[m] = card[index];
					card[index] = 0;
				}
			}
			// 补花
			ByteArray.Builder huacard = ByteArray.newBuilder();
			for (int k = 0; k < huapaiCount; k++) {
				Byte filled_card = remainCards.get(remainCards.size() - 1);
				remainCards.remove(remainCards.size() - 1);
				while (filled_card >= 56) {
					buhua_count += 1;
					huacard.addAByte(filled_card);
					huapai.add(filled_card);
					filled_card = remainCards.get(remainCards.size() - 1);
					remainCards.remove(remainCards.size() - 1);
				}
				card[16 - k] = filled_card;
				aplayfilledcard.add(filled_card);// 一个玩家补到牌的
			}
			ByteArray realhuacard = huacard.build();
			around.addCardH(realhuacard);
			
			mjhuapai[i] = new QzmjHuaPai();
			mjhuapai[i].cards = ArrayUtility.toByteArray(huapai);
			logger.info("花牌==={}",mjhuapai[i].cards);
			huapais.add(huapai);
			filled_cards.add(aplayfilledcard);// 按照顺序补牌的链表
			// logger.info("mj bu hua card={}", card);
			i++;
		}
		mjRound.setH_cards(huapais);
		// logger.info("buhua_count==========={}", buhua_count);
		mjRound.setBuhua_count(buhua_count);
		mjRound.setInit_hua((byte) buhua_count);
		// 补花结束后将手牌转化为了下标
		byte[][] cardIndex = mjRound.getCardIndex();
		int index = 0;
		for (byte[] aplay_cardIndex : cardIndex) {
			SwitchToCardIndex(cards[index], (byte) cards[index].length, aplay_cardIndex);
			index++;
		}
		int rm_size = mjRound.getRemain_card().size();
		// int god_shaizi = 5;
		int god_location = shaizi.get(0) + shaizi.get(1);
		while (remainCards.get(rm_size - god_location) >= 56) {
			god_location++;
			// shaizi.add((short) RandomUtils.nextInt(1, 7));// 翻金牌是翻到花牌继续摇色子
			// shaizi.add((short) RandomUtils.nextInt(1, 7));
			// god.add(remainCards.get(rm_size - god_location));
			// remainCards.remove(rm_size - god_location);// 移除花牌
			// god_shaizi += 2;
			// god_location = shaizi.get(god_shaizi - 1) + shaizi.get(god_shaizi) +
			// god_location; // 从上次花牌的地方往下数
		}
		god.add(remainCards.get(rm_size - god_location));// 最后一个为金牌
		// god.add((byte) 20);//
		// ------------------------------------------------------------测试
		//logger.info("god={}", god.get(god.size() - 1));//
        
		remainCards.remove(rm_size - god_location); // 花牌移除
		mjRound.setGod_card(god.get(god.size() - 1));// 设置金牌
		around.setGoldCard(god.get(god.size() - 1));
		//mjRound.setGod_card((byte) 20); //
		// -----------------------------------------------------------测试
		mjRound.setKaijin_saizi(shaizi);
		PushQzmjYaoshaizi pushmjyaoshaizi = new PushQzmjYaoshaizi();
		logger.info("麻将剩余牌数目={}", remainCards.size());

		pushmjyaoshaizi.Shaizi_num = ArrayUtility.toShortArray(shaizi);
		pushmjyaoshaizi.god_card = ArrayUtility.toByteArray(god);
		pushmjyaoshaizi.huapai = mjhuapai;
		for (int j = 0; j < mjRound.getPlayerIds().size(); j++) {
			pushmjyaoshaizi.card = 0;
			pushmjyaoshaizi.cards = ArrayUtility.toByteArray(filled_cards.get(j));// 只发补上的牌
			
			if (j == zhuangjia_index)
				pushmjyaoshaizi.card = Bankuser_card;
			int playid = mjRound.getPlayerIds().get(j);
			PlayingRole pr = SessionManager.getInstance().getPlayer(playid);
			if (pr != null && pr.isChannelActive()) {
				pr.writeAndFlush(pushmjyaoshaizi.build(pr.alloc()));
			}
			ByteArray.Builder fill = ByteArray.newBuilder();
			
			for(Byte card:filled_cards.get(j)) {
				fill.addAByte(card);
			}
			ByteArray realfill = fill.build();
			around.addHandsCard2(realfill);
		}
		ARound readlRound =  around.build();
		mjRound.setARound(readlRound);
		// -----------
		// cardIndex
		byte[] m_cbUserAction = mjRound.getM_cbUserAction();
		byte m_cbProvideCard = cards[zhuangjia_index][16];
		if (mjRound.getM_wReplaceUser() == QzmjConstants.INVALID_CHAIR) {
			int m_wCurrentUser = mjRound.getM_wCurrentUser();
			boolean[] m_bEnjoinChiHu = mjRound.getM_bEnjoinChiHu();
			TagWeaveItem[][] m_WeaveItemArray = mjRound.getM_WeaveItemArray();
			byte[] m_cbWeaveItemCount = mjRound.getM_cbWeaveItemCount();
			CChiHuRight chr = new CChiHuRight();
			if (!m_bEnjoinChiHu[m_wCurrentUser]) {
				int indexa = (byte) SwitchToCardIndex(m_cbProvideCard);
				cardIndex[m_wCurrentUser][indexa]--;
				byte cbAction = AnalyseChiHuCard(cardIndex[m_wCurrentUser], m_WeaveItemArray[m_wCurrentUser],
						m_cbWeaveItemCount[m_wCurrentUser], m_cbProvideCard, chr, mjRound);
				cardIndex[m_wCurrentUser][SwitchToCardIndex(m_cbProvideCard)]++;
				// 检查4台
				if ((cbAction & QzmjConstants.WIK_CHI_HU) > 0) {
					FiltrateRight(m_wCurrentUser, chr, mjRound);
					byte eyecard = Bankuser_card;
					if (Bankuser_card >= 56) {
						List<Byte> Bankusercard = filled_cards.get(zhuangjia_index);
						eyecard = Bankusercard.get(Bankusercard.size() - 1);
					}
					logger.info("winner card", eyecard);
					mjRound.setM_cbSendCardData(eyecard);
					// mjRound.setM_cbProvideCard(eyecard);
					// byte bFanshu = MjLogic.GetChiHuActionRank(chr, true);if
					// (m_cbUserAction[wCurrentUser] == MjConstants.WIK_CHI_HU) // 吃胡

					List<TagAnalyseItem> analyItem = mjRound.getAnalyseItemArray();
					List<Byte> singCardEye = mjRound.getSingCardEye().get(m_wCurrentUser);
				//	List<Byte> doubleCardEye = mjRound.getDoubleCardEye().get(m_wCurrentUser);
					singCardEye.clear();
				//	doubleCardEye.clear();
					for (TagAnalyseItem tag : analyItem) {
						if (!tag.bMagicEye)
							continue;
					//	if (tag.cbCardEye == mjRound.getGod_card()) {
					//		doubleCardEye.add(tag.cbCardEye);
					//	} else {
							singCardEye.add(tag.cbCardEye);
					//	}
					}

				}
				m_cbUserAction[m_wCurrentUser] |= cbAction;
			}
			// 杠牌判断
			if (mjRound.getM_bEnjoinChiPeng()[zhuangjia_index] == false) {
				TagGangCardResult GangCardResult = new TagGangCardResult();
				// byte m_cbUserAction1[] = mjround.getM_cbUserAction();
				mjRound.getM_wCurrentUser();
				m_cbUserAction[zhuangjia_index] |= AnalyseGangCard(cardIndex[zhuangjia_index],
						m_WeaveItemArray[m_wCurrentUser], m_cbWeaveItemCount[m_wCurrentUser], GangCardResult,
						mjRound.getGod_card());
			}
		}
		if (m_cbUserAction[zhuangjia_index] > 0) // 存在动作
		{
			SendOperateNotify(mjRound, m_cbProvideCard);
		}
	}

	public void testRoundOver(QzmjRound mjround) {
		
		short score[] = mjround.getM_lGameScore();
		
		ARound around = mjround.getARound();
		AllRound allround = mjround.getAllround();
		AllRound.Builder modallround = allround.toBuilder();
		modallround.addRounds(around);
		for(int i =0;i<score.length;i++) {
			modallround.addAllGameSocre(score[i]);
		}
		List<Integer> allplay = mjround.getPlayerIds();
	//	modallround.addAllGameSocre();
		AllRound realallround = modallround.build();
		mjround.setAllround(realallround);
		BattleReport baRt = new BattleReport();
		baRt.setAllround(realallround);
		baRt.setRoomtype((byte)RoomType.QzmjRoom);
		baRt.setId(BattleReportManager.getInstance().getReportId());
		BattleReportDBHelper.getInstance().asyncAddBattleReport(baRt); 
		Battlename.Builder playermsg = Battlename.newBuilder();
		int j = 0;
		for(Integer apl:allplay) {
			PlayerBean poc = RoomDataManager.getInstance().getPlayerBean(apl);
			Player.Builder aplay = Player.newBuilder();
			aplay.setId(apl);
			aplay.setSocre(score[j]);
			aplay.setName(poc.getName());
			Player realplay= aplay.build();
			playermsg.addPlayers(realplay);
			j++;
		}
		Battlename realplay = playermsg.build();
		for(Integer aplayer:allplay) {
			PlayerReport playreport = new PlayerReport();
			playreport.setBattleperortId(baRt.getId());
			playreport.setDate(new Date());
			playreport.setGame_type(RoomType.QzmjRoom);
			playreport.setPlayerId(aplayer);
			playreport.setRoomid(mjround.getRoomUuid());
			playreport.setPlayers(realplay);
			PlayerReportDBHelper.getInstance().asyncAddPlayerReport(playreport);
		}
		
		
		if (mjround.getCost_type() == 2&&mjround.getFee()>0) {
			
			List<Integer> play = new ArrayList<Integer>();
			
			int maxPlayerIndex = 0;
			for (int i = 0; i < score.length; i++) {
				if (score[i] == maxPlayerIndex)
					play.add(allplay.get(i));
				if (score[i] > maxPlayerIndex) {
					play.clear();
					play.add(allplay.get(i));
					maxPlayerIndex = score[i];
				}
				
			}

			sendQzmjCalculateFangka(mjround.getFee(), mjround.getCost_type(), mjround.getPlayerIds());
		}
		
		List<Integer> players = mjround.getPlayerIds();
		for (Integer aPlayerId : players) {
			QzmjDatamanager.getInstance().removePlayer(aPlayerId);
		}
		mjround.setM_lGameScore(null);
		mjround.setM_bTrustee(null);
		mjround.setM_bTianDiHu(null);
		mjround.setM_cbFengCardData(null);
		mjround.setM_bEnjoinChiHu(null);
		mjround.setM_bEnjoinChiPeng(null);
		mjround.setM_bResponse(null);// 响应
		mjround.setM_cbUserAction(null);
		mjround.setM_cbOperateCard(null);
		mjround.setM_cbPerformAction(null);
		mjround.setM_cbWeaveItemCount(null);
		mjround.setM_WeaveItemArray(null);
		mjround.setM_dwChiHuKind(null);
		mjround.setM_ChiHuRight(null);
		mjround.setCards(null);
		mjround.setCardIndex(null);
		mjround.setPlayReady(null);
		mjround.setGenFeng(null);
		mjround.setZiMo(null);
		mjround.setJiePao(null);
		mjround.setDianPao(null);
		mjround.setMingGang(null);
		mjround.setAnGang(null);
		mjround.setSingGold(null);
		mjround.setSanJingDao(null);
		mjround.setThreeGold(null);
		mjround.setKindItem(null);
		mjround.setPlayerIds(null);
		mjround.setRemain_card(null);
		mjround.setEnter_player(null);
		mjround.setH_cards(null);
		mjround.setPushed_card(null);
		mjround.setAnalyseItemArray(null);
		mjround.setSingCardEye(null);
		mjround.setDoubleCardEye(null);
		// 全部对局结束的消息
	}

	public void nextRound(QzmjRound mjround) {
		ARound around = mjround.getARound();
		AllRound allround = mjround.getAllround();
		AllRound.Builder modallround = allround.toBuilder();
		modallround.addRounds(around);
		AllRound realallround = modallround.build();
		mjround.setAllround(realallround);
		mjround.setWait_game((byte) 0);
		int sumRound = mjround.getRoundSum();
		if (sumRound <= 0)
			return; // 房间结束
		randCard(mjround);
		
		mjround.setGamestart(false);
		mjround.setM_wReplaceUser(QzmjConstants.INVALID_CHAIR); // 设置为不可的
		boolean[] genfeng = mjround.getGenFeng(); // 是否要跟大牌
		ZeroMemory(genfeng);
		byte[][] card_index = mjround.getCardIndex(); // 获得手牌数组下标
		ZeroMemory(card_index); // 清空
		boolean[] trustee = mjround.getM_bTrustee(); // 获得是否托管
		ZeroMemory(trustee);
		boolean[] tiandihu = mjround.getM_bTianDiHu(); // 天胡状态
		ZeroMemory(tiandihu);
		// mjround.setM_cbFengCardData(new byte[4]); // 记录蜂派
		boolean[] M_bEnjoinChiHu = mjround.getM_bEnjoinChiHu();// 禁止吃胡
		ZeroMemory(M_bEnjoinChiHu);
		boolean[] M_bEnjoinChiPeng = mjround.getM_bEnjoinChiPeng();// 禁止吃碰
		ZeroMemory(M_bEnjoinChiPeng);
		boolean[] M_bResponse = mjround.getM_bResponse();// 响应标志
		ZeroMemory(M_bResponse);
		byte[] m_cbuseraction = mjround.getM_cbUserAction();// 用户动作
		ZeroMemory(m_cbuseraction);
		byte[][] M_cbOperateCard = mjround.getM_cbOperateCard(); // 操作扑克
		ZeroMemory(M_cbOperateCard);
		byte[] M_cbPerformAction = mjround.getM_cbPerformAction(); // 执行动作
		ZeroMemory(M_cbPerformAction);
		byte[] M_cbWeaveItemCount = mjround.getM_cbWeaveItemCount(); // 组合数目
		ZeroMemory(M_cbWeaveItemCount);
		boolean singgold[] = mjround.getSingGold(); // 单游
		ZeroMemory(singgold);
		boolean doublegold[] = mjround.getDoubleGold();// 双游
		ZeroMemory(doublegold);
		boolean ThreeGold[] = mjround.getThreeGold();// 三游
		ZeroMemory(ThreeGold);
		boolean sanjin[] = mjround.getThreeGold();// 三金倒
		ZeroMemory(sanjin);
		List<List<Byte>> pushed_card = mjround.getPushed_card();// 出牌列表
		
		for (List<Byte> a_playCard : pushed_card) {
			a_playCard.clear();
		}
		
		// byte[] singlecard = mjround.getSingCardEye();
		// ZeroMemory(singlecard);
		// byte[] doublecard = mjround.getDoubleCardEye();
		// ZeroMemory(doublecard);
		mjround.setM_cbSendCardData(0); // 发牌的扑克
		// boolean playread[] = mjround.getPlayReady();
		// mjround.setM_cbOutCardCount(0); // 出牌数目
		// mjround.setM_cbSendCardData(0); // 发牌的扑克
		// mjround.setCards(new byte[MjConstants.GAME_PLAYER][17]); //牌
		// List<Byte> remain_card = new LinkedList<>();
		// mjround.setRemain_card(remain_card);
		boolean[] playReady = mjround.getPlayReady(); // 记录玩家准备状态
		ZeroMemory(playReady);
		TagWeaveItem[][] tagWeaveItem = mjround.getM_WeaveItemArray();// 所有组合
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 5; j++) {
				tagWeaveItem[i][j].cbWeaveKind = 0;
				tagWeaveItem[i][j].cbCenterCard = 0;
				tagWeaveItem[i][j].cbPublicCard = 0;
				tagWeaveItem[i][j].wProvideUser = 0;
				ZeroMemory(tagWeaveItem[i][j].cbCardData);
			}
		}
		byte[] M_dwChiHuKind = mjround.getM_dwChiHuKind(); // 吃胡结果
		ZeroMemory(M_dwChiHuKind);

		CChiHuRight[] CChiHuRight = mjround.getM_ChiHuRight();
		List<List<Byte>> singCardEye = mjround.getSingCardEye();
		List<List<Byte>> doubleCardEye = mjround.getDoubleCardEye();
		for (int i = 0; i < 4; i++) {
			CChiHuRight[i].SetEmpty();
			singCardEye.get(i).clear();
			doubleCardEye.get(i).clear();
		}
		mjround.setM_wCurrentUser(mjround.getM_wBankerUser()); // 当前出牌玩家
		mjround.setM_wProvideUser(mjround.getM_wBankerUser()); //

	}

	public boolean DispatchCardData(int wCurrentUser, boolean bTail, QzmjRound mjround) {
		// 状态效验
		assert (wCurrentUser != QzmjConstants.INVALID_CHAIR);
		if (wCurrentUser == QzmjConstants.INVALID_CHAIR)
			return false;
		assert (mjround.isM_bSendStatus());
		if (mjround.isM_bSendStatus() == false)
			return false;

		// 丢弃扑克
		if ((mjround.getM_wReplaceUser() == QzmjConstants.INVALID_CHAIR)
				&& (mjround.getM_wOutCardUser() != QzmjConstants.INVALID_CHAIR)
				&& (mjround.getM_cbOutCardData() != 0)) {
		}

		// 荒庄结束
		if (mjround.getRemain_card().size() == QzmjConstants.m_cbEndLeftCount) {
			mjround.setM_wProvideUser(QzmjConstants.INVALID_CHAIR);// m_wProvideUser=MjConstants.INVALID_CHAIR;
			// 游戏结束
			return true;
		}

		// 设置变量
		if (mjround.getM_wReplaceUser() == QzmjConstants.INVALID_CHAIR) {
			mjround.setM_cbOutCardData((byte) 0);// m_cbOutCardData=0;
			mjround.setM_wCurrentUser(wCurrentUser);// m_wCurrentUser=wCurrentUser;
			mjround.setM_wOutCardUser(QzmjConstants.INVALID_CHAIR);// m_wOutCardUser=INVALID_CHAIR;
		}

		// 发送扑克

		int m_cbSendCardData = mjround.getM_cbSendCardData();
		List<Byte> m_cbRepertoryCard = mjround.getRemain_card();
		m_cbSendCardData = m_cbRepertoryCard.get(0);
		mjround.setM_cbSendCardData(m_cbSendCardData);
		m_cbRepertoryCard.remove(0);
		ARound around = mjround.getARound();
		ARound.Builder modAround = around.toBuilder();
		AllAction.Builder aAction = AllAction.newBuilder();
		//ByteArray.Builder opc = ByteArray.newBuilder();
		aAction.setUserAction(QzmjConstants.battle_mopai);
		aAction.setPlayerIndex(wCurrentUser);
		aAction.addOperatorCards(m_cbSendCardData);
		modAround.addActions(aAction);
		ARound modedround = modAround.build();
		mjround.setARound(modedround);
		
		//aAction.setO
		
		// 补花
		if (m_cbSendCardData >= 56) {
			
			ARound thisaround = mjround.getARound();
			ARound.Builder moAround = thisaround.toBuilder();
			AllAction.Builder thisAction = AllAction.newBuilder();

			thisAction.setUserAction(QzmjConstants.battle_buhua);
			thisAction.setPlayerIndex(wCurrentUser);
			aAction.addOperatorCards(m_cbSendCardData);
	
			moAround.addActions(thisAction);
			ARound moderound = moAround.build();
			mjround.setARound(moderound);
			
			mjround.setBuhua_count((byte) (mjround.getBuhua_count() + 1));
			List<List<Byte>> huapais = mjround.getH_cards();
			huapais.get(wCurrentUser).add((byte) m_cbSendCardData);
			PushQzmjBuHua pushBuHua = new PushQzmjBuHua();
			pushBuHua.HuaCard = (byte) m_cbSendCardData;
			pushBuHua.user_index = (byte) wCurrentUser;
			List<Integer> playerIds = mjround.getPlayerIds();
			for (int i = 0; i < playerIds.size(); i++) {
				PlayingRole pr = SessionManager.getInstance().getPlayer(playerIds.get(i));
				if (pr != null && pr.isChannelActive()) {
					pr.writeAndFlush(pushBuHua.build(pr.alloc()));
				}
			}
			DispatchCardData(wCurrentUser, true, mjround);
			return true; // 补花重新补牌
		}
        
		// 加牌
		byte[][] m_cbCardIndex = mjround.getCardIndex();
		m_cbCardIndex[wCurrentUser][SwitchToCardIndex((byte) m_cbSendCardData)]++;
		logger.info("mj mopai playerIndex={} pai={}", wCurrentUser, m_cbSendCardData);
		mjround.setM_wReplaceUser(QzmjConstants.INVALID_CHAIR);
		if (mjround.getM_wCurrentUser() == wCurrentUser) {
			// 设置变量
			mjround.setM_wProvideUser(wCurrentUser);// m_wProvideUser=wCurrentUser;
			mjround.setM_cbProvideCard(m_cbSendCardData);// m_cbProvideCard=m_cbSendCardData;
		}
		byte[] m_cbUserAction = mjround.getM_cbUserAction();
		byte m_cbProvideCard = (byte) mjround.getM_cbProvideCard();
		if (mjround.getM_wReplaceUser() == QzmjConstants.INVALID_CHAIR) {
			int m_wCurrentUser = mjround.getM_wCurrentUser();
			boolean[] m_bEnjoinChiHu = mjround.getM_bEnjoinChiHu();
			TagWeaveItem[][] m_WeaveItemArray = mjround.getM_WeaveItemArray();
			byte[] m_cbWeaveItemCount = mjround.getM_cbWeaveItemCount();
			CChiHuRight chr = new CChiHuRight();
			if (!m_bEnjoinChiHu[m_wCurrentUser]) {

				// 胡牌判断 CChiHuRight chr;
				m_cbCardIndex[m_wCurrentUser][SwitchToCardIndex(m_cbProvideCard)]--;
				byte cbAction = AnalyseChiHuCard(m_cbCardIndex[m_wCurrentUser], m_WeaveItemArray[m_wCurrentUser],
						m_cbWeaveItemCount[m_wCurrentUser], m_cbProvideCard, chr, mjround);
				m_cbCardIndex[m_wCurrentUser][SwitchToCardIndex(m_cbProvideCard)]++;
				// 检查4台
				if ((cbAction & QzmjConstants.WIK_CHI_HU) > 0) {
					FiltrateRight(m_wCurrentUser, chr, mjround);
				}

				m_cbUserAction[m_wCurrentUser] |= cbAction;
			}

			// 杠牌判断

			if (mjround.getM_bEnjoinChiPeng()[wCurrentUser] == false) {
				TagGangCardResult GangCardResult = new TagGangCardResult();
				// byte m_cbUserAction1[] = mjround.getM_cbUserAction();
				mjround.getM_wCurrentUser();
				m_cbUserAction[wCurrentUser] |= AnalyseGangCard(m_cbCardIndex[wCurrentUser],
						m_WeaveItemArray[m_wCurrentUser], m_cbWeaveItemCount[m_wCurrentUser], GangCardResult,
						mjround.getGod_card());
			}
		}
		List<Integer> players = mjround.getPlayerIds();
		List<Byte> singCardEye = mjround.getSingCardEye().get(wCurrentUser);
		//List<Byte> doubleCardEye = mjround.getDoubleCardEye().get(wCurrentUser);
		List<TagAnalyseItem> analyItem = mjround.getAnalyseItemArray();
		//doubleCardEye.clear();
		singCardEye.clear();
		if (m_cbUserAction[wCurrentUser] == QzmjConstants.WIK_CHI_HU) // 吃胡
		{
			for (TagAnalyseItem tag : analyItem) {
				if (!tag.bMagicEye)
					continue;
					singCardEye.add(tag.cbCardEye);
			}
			boolean sin[] = mjround.getThreeGold();
			boolean dou[] = mjround.getDoubleGold();
	//		boolean three[] = mjround.getThreeGold();
			if(singCardEye.size()>0||sin[wCurrentUser]||dou[wCurrentUser]) {
				PushQzmjJinState pus = new PushQzmjJinState();
				pus.type = 1;
				if(sin[wCurrentUser])
					pus.type = 2;
				if(dou[wCurrentUser])
					pus.type = 3;
				pus.cards = ArrayUtility.toByteArray(singCardEye);
				int playerid = players.get(wCurrentUser);
				PlayingRole pr = SessionManager.getInstance().getPlayer(playerid);
				if(pr != null && pr.isChannelActive()) {
					pr.writeAndFlush(pus.build(pr.alloc()));
				}
			}

		}
		PushQzmjMopai pushmopai = new PushQzmjMopai();
		// logger.info("msg={}", pushmopai);
		for (Integer aplay : players) {
			PlayingRole pr = SessionManager.getInstance().getPlayer(aplay);
			if (pr != null && pr.isChannelActive()) {
				// pushGameStart.my_cards = ArrayUtility.toByteArray(cardsList);
				pushmopai.mopai_index = (short) wCurrentUser;
				pushmopai.pai = 0;
				if (players.indexOf(aplay) == wCurrentUser) {
					pushmopai.pai = (byte) m_cbSendCardData;
				}
				pr.writeAndFlush(pushmopai.build(pr.alloc()));
			}
		}
		if (m_cbUserAction[wCurrentUser] > 0) // 存在动作
		{
			SendOperateNotify(mjround, m_cbProvideCard);
		}
		return true;
	}

	public boolean EstimateUserRespond(int wCenterUser, byte cbCenterCard, int EstimatKind, QzmjRound mjround) {

		// logger.info("mj fenxi action");
		if (cbCenterCard == mjround.getGod_card())
			return false;
		// 变量定义
		boolean bAroseAction = false;
		// 用户状态
		boolean[] m_bResponse = mjround.getM_bResponse();
		byte[] m_cbUserAction = mjround.getM_cbUserAction();
		byte[] m_cbPerformAction = mjround.getM_cbPerformAction();
		byte mgindex = SwitchToCardIndex(mjround.getGod_card());
		ZeroMemory(m_bResponse);
		ZeroMemory(m_cbUserAction); // 清空里面的数据
		ZeroMemory(m_cbPerformAction);

		byte[][] m_cbCardIndex = mjround.getCardIndex();
		int m_wPlayerCount = mjround.getPlayerIds().size();
		// int m_cbLeftCardCount = mjround.getRemain_card().size();
		boolean m_bEnjoinChiPeng[] = mjround.getM_bEnjoinChiPeng();
		boolean m_bEnjoinChiHu[] = mjround.getM_bEnjoinChiHu();
		// 动作判断
		for (int i = 0; i < m_wPlayerCount; i++) {
			// 用户过滤
			if (wCenterUser == i)
				continue;

			// 出牌类型
			if (EstimatKind == QzmjConstants.EstimatKind_OutCard) {
				// 吃碰判断
				if (m_bEnjoinChiPeng[i] == false) {
					// 碰牌判断
					m_cbUserAction[i] |= EstimatePengCard(m_cbCardIndex[i], cbCenterCard);

					// 吃牌判断
					int wEatUser = wCenterUser + 1;
					if (wEatUser >= 4)
						wEatUser = 0;
					if (wEatUser == i)
						m_cbUserAction[i] |= EstimateEatCard(m_cbCardIndex[i], cbCenterCard, mjround);

					// 杠牌判断
					if (mjround.getRemain_card().size() > QzmjConstants.m_cbEndLeftCount) {
						m_cbUserAction[i] |= EstimateGangCard(m_cbCardIndex[i], cbCenterCard, mjround);
					}
				}
			}

			// 胡牌判断
			if (m_bEnjoinChiHu[i] == false) {
				// 吃胡判断
				CChiHuRight chr = new CChiHuRight();
				byte cbWeaveCount = (byte) mjround.getM_cbWeaveItemCount()[i];
				TagWeaveItem[][] m_WeaveItemArray = mjround.getM_WeaveItemArray();
				byte cbAction = 0;
				if (m_cbCardIndex[i][mgindex] <= 1)// 对别人的动作响应，没有金牌
				{
					// if(m_cbCardIndex[i][mgindex] == 2)

					cbAction = AnalyseChiHuCard(m_cbCardIndex[i], m_WeaveItemArray[i], cbWeaveCount, cbCenterCard, chr,
							mjround);
				}
				// logger.info("吃胡={}",cbAction);
				// 检查4台
				if ((cbAction & QzmjConstants.WIK_CHI_HU) > 0) {
					FiltrateRight(i, chr, mjround);
					// byte bFanshu = MjLogic.GetChiHuActionRank(chr, true);
				}

				
				
				m_cbUserAction[i] |= cbAction;
				List<Byte> singCardEye = mjround.getSingCardEye().get(i);
				singCardEye.clear();
				if (m_cbUserAction[i] > QzmjConstants.WIK_CHI_HU) // 吃胡
				{
					List<TagAnalyseItem> analyItem = mjround.getAnalyseItemArray();
					
					for (TagAnalyseItem tag : analyItem) {
						if (!tag.bMagicEye)
							continue;
							singCardEye.add(tag.cbCardEye);
					}

				}
			}

			// 结果判断
			if (m_cbUserAction[i] != QzmjConstants.WIK_NULL)
				bAroseAction = true;
		}
        //
		
		// 结果处理
		if (bAroseAction == true) {
			// 设置变量
			mjround.setM_wProvideUser(wCenterUser);
			mjround.setM_cbProvideCard(cbCenterCard);
			mjround.setM_wReplaceUser(mjround.getM_wCurrentUser());
			mjround.setM_wCurrentUser(QzmjConstants.INVALID_CHAIR);
			logger.info("msg------action={}", m_cbUserAction);
			SendOperateNotify(mjround, cbCenterCard);

			return true;
		}

		return false;

	}

	// 碰牌判断
	public Byte EstimatePengCard(final byte cbCardIndex[], byte cbCurrentCard) {
		assert (IsValidCard(cbCurrentCard));
		if (IsHuaCard(cbCurrentCard))
			return QzmjConstants.WIK_NULL;
		// 碰牌判断
		if (cbCardIndex[SwitchToCardIndex(cbCurrentCard)] >= 2)
			return QzmjConstants.WIK_PENG;
		else
			return QzmjConstants.WIK_NULL;
	}

	// 杠牌判断
	public Byte EstimateGangCard(final byte cbCardIndex[], byte cbCurrentCard, QzmjRound mjround) {
		// 参数效验
		assert (IsValidCard(cbCurrentCard));

		// 过滤判断
		if (IsMagicCard(cbCurrentCard, false, mjround.getGod_card()) || IsHuaCard(cbCurrentCard))
			return QzmjConstants.WIK_NULL;

		if (cbCardIndex[SwitchToCardIndex(cbCurrentCard)] == 3)
			return QzmjConstants.WIK_GANG;
		else
			return QzmjConstants.WIK_NULL;
		// 杠牌判断
		// return
		// (cbCardIndex[SwitchToCardIndex(cbCurrentCard)]==3)?MjConstants.WIK_GANG:MjConstants.WIK_NULL;
	}

	// 动作等级
	public byte GetUserActionRank(byte cbUserAction) {
		// 胡牌等级
		if ((cbUserAction & QzmjConstants.WIK_CHI_HU) > 0) {
			return 4;
		}

		// 杠牌等级
		if ((cbUserAction & QzmjConstants.WIK_GANG) > 0) {
			return 3;
		}

		// 碰牌等级
		if ((cbUserAction & QzmjConstants.WIK_PENG) > 0) {
			return 2;
		}

		// 上牌等级
		if ((cbUserAction & (QzmjConstants.WIK_RIGHT | QzmjConstants.WIK_CENTER | QzmjConstants.WIK_LEFT)) > 0) {
			return 1;
		}

		return 0;
	}

	// 胡牌等级
	public byte GetChiHuActionRank(final CChiHuRight ChiHuRight, boolean bCheckFan/* = false */) {
		// 4番 特殊牌型 天胡 地胡 硬八对 单钓 三财神
		if (!ChiHuRight.Yu(QzmjConstants.CHR_BA_DUI_YING).IsEmpty()
				|| !ChiHuRight.Yu(QzmjConstants.CHR_TIAN_HU).IsEmpty()
				|| !ChiHuRight.Yu(QzmjConstants.CHR_DI_HU).IsEmpty()
				|| !ChiHuRight.Yu(QzmjConstants.CHR_THREE_KING).IsEmpty())
			return 4;

		// 2番 硬牌 八对
		if (!ChiHuRight.Yu(QzmjConstants.CHR_BA_DUI).IsEmpty() || !ChiHuRight.Yu(QzmjConstants.CHR_YING_HU).IsEmpty())
			return 2;

		// 1番 其余都是软胡
		return 1;
	}

	public boolean IsHuaCard(byte cbCardData) {
		assert (IsValidCard(cbCardData));
		return cbCardData >= 0x38 ? true : false;
	}

	public Byte EstimateEatCard(final byte cbCardIndex[], byte cbCurrentCard, QzmjRound mj) {
		if (!mj.isAllow_eatcard())
			return QzmjConstants.WIK_NULL;

		// 参数效验
		assert (IsValidCard(cbCurrentCard));

		int m_cbMagicIndex = SwitchToCardIndex(mj.getGod_card());
		// 过滤判断
		if ((cbCurrentCard >= 0x31 && cbCurrentCard <= 0x37))
			return QzmjConstants.WIK_NULL;

		// 变量定义
		byte[] cbExcursion = new byte[] { 0, 1, 2 };
		byte[] cbItemKind = new byte[] { QzmjConstants.WIK_LEFT, QzmjConstants.WIK_CENTER, QzmjConstants.WIK_RIGHT };
		byte cbInsteadCard = cbCurrentCard;
		byte[] cbInsteadIndex = new byte[QzmjConstants.MAX_INDEX];
		// System.out.println("MjConstants.MAX_INDEX" + QzmjConstants.MAX_INDEX);
		cbInsteadIndex = Arrays.copyOf(cbCardIndex, cbCardIndex.length);
		if (cbInsteadIndex[m_cbMagicIndex] > 0) {
			cbInsteadIndex[m_cbMagicIndex] = 0;
		}
		// 替换白板
		// if ((m_cbMagicIndex != (byte) QzmjConstants.MAX_INDEX) &&
		// (SwitchToCardData((byte) m_cbMagicIndex) != 0x37)) {
		// // 当前牌
		// if (cbCurrentCard == 0x37 && !IsMagicCard(cbCurrentCard, false,
		// mj.getGod_card()))
		// cbInsteadCard = SwitchToCardData((byte) m_cbMagicIndex);
		//
		// // 手中牌
		// //System.out.println("length" + cbInsteadIndex);
		// cbInsteadIndex[m_cbMagicIndex] = cbInsteadIndex[33];
		// cbInsteadIndex[33] = 0;
		// }

		// 吃牌判断
		byte cbEatKind = 0, cbFirstIndex = 0;
		byte cbCurrentIndex = SwitchToCardIndex(cbInsteadCard);
		for (byte i = 0; i < cbItemKind.length; i++) {
			byte cbValueIndex = (byte) (cbCurrentIndex % 9);
			if ((cbValueIndex >= cbExcursion[i]) && ((cbValueIndex - cbExcursion[i]) <= 6)) {
				// 吃牌判断
				cbFirstIndex = (byte) (cbCurrentIndex - cbExcursion[i]);

				if ((cbCurrentIndex != cbFirstIndex) && (cbInsteadIndex[cbFirstIndex] == 0))
					continue;
				if ((cbCurrentIndex != (cbFirstIndex + 1)) && (cbInsteadIndex[cbFirstIndex + 1] == 0))
					continue;
				if ((cbCurrentIndex != (cbFirstIndex + 2)) && (cbInsteadIndex[cbFirstIndex + 2] == 0))
					continue;

				// 设置类型
				cbEatKind |= cbItemKind[i];
			}
		}

		return cbEatKind;
	}

	public byte AnalyseChiHuCard(final byte cbCardIndex[], final TagWeaveItem WeaveItem[], byte cbWeaveCount,
			byte cbCurrentCard, CChiHuRight ChiHuRight, QzmjRound mjround) {
		// 变量定义
		byte god_card = mjround.getGod_card();
		byte cbChiHuKind = QzmjConstants.WIK_NULL;
		List<TagAnalyseItem> AnalyseItemArray = mjround.getAnalyseItemArray();
		if (!AnalyseItemArray.isEmpty())
			AnalyseItemArray.clear();
		// 设置变量
		ChiHuRight.SetEmpty();

		// 构造扑克
		byte cbCardIndexTemp[] = new byte[QzmjConstants.MAX_INDEX];
		System.arraycopy(cbCardIndex, 0, cbCardIndexTemp, 0, QzmjConstants.MAX_INDEX);
		// cbCurrentCard一定不为0 !!!!!!!!!
		assert (cbCurrentCard != 0);
		if (cbCurrentCard == 0)
			return QzmjConstants.WIK_NULL;

		// 插入扑克
		if (cbCurrentCard != 0)
			cbCardIndexTemp[SwitchToCardIndex(cbCurrentCard)]++;

		if (IsSanJinDao(cbCardIndexTemp, god_card) && mjround.isAllow_sanjindao()) {
			ChiHuRight.HuoFuzhi(QzmjConstants.CHR_THREE_KING);
			cbChiHuKind = QzmjConstants.WIK_CHI_HU;

		}
		// 分析扑克
		AnalyseCard(cbCardIndexTemp, WeaveItem, cbWeaveCount, AnalyseItemArray, god_card, mjround);
		// 胡牌分析
		if (AnalyseItemArray.size() > 0) {
			// 牌型分析
			// for (int i = 0; i < AnalyseItemArray.size(); i++) {
			// // 变量定义
			// TagAnalyseItem pAnalyseItem = AnalyseItemArray.get(i);
			// // 判断番型
			// // if (IsPengPeng(pAnalyseItem))
			// // ChiHuRight.HuoFuzhi(MjConstants.CHR_PENG_PENG_HU);
			// // ChiHuRight |= CHR_PENG_PENG_HU;
			// // 硬胡软胡
			// if (IsYingHu(pAnalyseItem, cbWeaveCount, god_card))
			// ChiHuRight.HuoFuzhi(MjConstants.CHR_YING_HU);
			// else
			// ChiHuRight.HuoFuzhi(MjConstants.CHR_RUAN_HU);
			// }

			cbChiHuKind = QzmjConstants.WIK_CHI_HU;
		}
		if (!ChiHuRight.IsEmpty())
			cbChiHuKind = QzmjConstants.WIK_CHI_HU;

		if (cbChiHuKind == QzmjConstants.WIK_CHI_HU) {
			// 判断番型
		}
		
		return cbChiHuKind;
	}

	public byte GetCardCount(final byte cbCardIndex[]) {
		// 数目统计
		byte cbCardCount = 0;
		for (byte i = 0; i < QzmjConstants.MAX_INDEX; i++)
			cbCardCount += cbCardIndex[i];

		return cbCardCount;
	}

	public boolean IsMagicCard(byte cbCardData, boolean bIsIndex, byte god_card) {
		byte cbCardIndex = cbCardData;
		if (!bIsIndex)
			cbCardIndex = SwitchToCardIndex(cbCardData);
		byte m_cbMagicIndex = SwitchToCardIndex(god_card);

		return (cbCardIndex == m_cbMagicIndex);

	}

	public boolean OnEventGameConclude(boolean liuju, QzmjRound mjround) {
		logger.info("mj game over");
		mjround.setWait_game((byte) 1);
		int wWinner = QzmjConstants.INVALID_CHAIR;
		byte[] m_dwChiHuKind = mjround.getM_dwChiHuKind();
		byte[][] m_cbCardIndex = mjround.getCardIndex();
		List<Integer> players = mjround.getPlayerIds();
		int bankuser = mjround.getM_wBankerUser();// 庄家
		byte[][] card_index = mjround.getCardIndex();// 得到玩家手牌
		short sumRound = mjround.getRoundSum();
		List<List<Byte>> huaCards = mjround.getH_cards();
		///if(!mjround.getIsYike())//不是一刻
		sumRound--;
		mjround.setRoundSum(sumRound); // 减少一局
		byte LianZzhuang_Count = mjround.getM_cbLianZhuangCount();

		byte ChiHuCard = mjround.getM_cbChiHuCard();
		byte[][] card_data = new byte[4][17];
		short[] Score = new short[4];
		short Sum_score[] = mjround.getM_lGameScore();
		PushQzmjGameOver pushgame = new PushQzmjGameOver();
		pushgame.huapai = new QzmjHuaPai[4];
		pushgame.Cards = new QzmjPlayerCard[4];
		pushgame.card_eye = 0;
		if (liuju == true) {// 没有玩家赢
			mjround.setM_cbLianZhuangCount((byte) (LianZzhuang_Count + 1));
			for (int i = 0; i < QzmjConstants.GAME_PLAYER; i++) {
				SwitchToCardData(m_cbCardIndex[i], card_data[i]);
				QzmjPlayerCard playcard = new QzmjPlayerCard();
				playcard.cards = card_data[i];
				pushgame.Cards[i] = playcard;
				QzmjHuaPai ahua = new QzmjHuaPai();
				ahua.cards = ArrayUtility.toByteArray(huaCards.get(i));
				pushgame.huapai[i] = ahua;
			}
			pushgame.socre = Score;
			pushgame.winner_index = -1;
			pushgame.Hu_type = 0;
			pushgame.analyseitem = null;
			for (int i = 0; i < players.size(); i++) {
				PlayingRole pr = SessionManager.getInstance().getPlayer(players.get(i));
				if (pr != null && pr.isChannelActive()) {
					pr.writeAndFlush(pushgame.build(pr.alloc()));
				}
			}
			if (sumRound <= 0) {
				RoundOver(mjround);
				testRoundOver(mjround);
			}
			return true;
		}
		// 不是臭庄
		TagWeaveItem[][] weavenItem = mjround.getM_WeaveItemArray();

		for (int i = 0; i < QzmjConstants.GAME_PLAYER; i++) {
			if (m_dwChiHuKind[i] == QzmjConstants.WIK_CHI_HU)
				wWinner = i;
			SwitchToCardData(m_cbCardIndex[i], card_data[i]);
			QzmjPlayerCard playcard = new QzmjPlayerCard();
			playcard.cards = card_data[i];
			pushgame.Cards[i] = playcard;
			QzmjHuaPai ahua = new QzmjHuaPai();
			ahua.cards = ArrayUtility.toByteArray(huaCards.get(i));
			pushgame.huapai[i] = ahua;
		}

	//	TagWeaveItem[] Aplerweaven = weavenItem[wWinner];
		byte Zimo[] = mjround.getZiMo();
		byte JiePao[] = mjround.getJiePao();
		byte DianPao[] = mjround.getDianPao();
		byte MingGang[] = mjround.getMingGang();
		byte AnGang[] = mjround.getAnGang();
		
		byte kezi[] = new byte[4]; //刻翻
		byte goldfan[] = new byte[4];//金翻
		byte huafan[] = new byte[4];//花翻
		byte j =0;
		for (TagWeaveItem[] Aplerweaven : weavenItem) {
			//byte KeZiFan = 0;
			for (TagWeaveItem aweave : Aplerweaven) {
				if (aweave.cbWeaveKind == 8 && aweave.cbCenterCard > 41) {
					kezi[j] += 1;
				}
				if (aweave.cbWeaveKind == 16) {
						
					kezi[j] += 2;
					if(aweave.wProvideUser==j)
						kezi[j] +=1;
					if(aweave.cbCenterCard>41)
						kezi[j] += 1;

				}
			}
			for(int i =0;i<card_index[j].length;i++) {
				if (card_index[j][i] >= 3) {
					kezi[j] += 1;
					if (i > 26)
						kezi[j] += 1;
				}
			}
			j++;
		}
        for(int i =0;i<QzmjConstants.GAME_PLAYER;i++) {
        	goldfan[i] = card_index[i][SwitchToCardIndex(mjround.getGod_card())];// 获取金牌的个数
        	huafan[i] = jugde_HuaFan(huaCards.get(i));
        }
		byte Hu_type = jugde_Hu_type((byte) wWinner, mjround);
		byte wFanShu = jugde_FanShu((byte) wWinner, mjround);
		List<Byte> player_index = new ArrayList<>();
        for(byte pl=0;pl<QzmjConstants.GAME_PLAYER;pl++) {
        	if(pl == wWinner)
        		continue;
        	player_index.add(pl);
        }
        
		if (bankuser == wWinner) {
			// basescore = basescore * 2;庄家赢三家
			Score[wWinner] += ((QzmjConstants.Zhuang_Score+ LianZzhuang_Count*QzmjConstants.Base_Score) * 3
					+ (kezi[wWinner] + goldfan[wWinner] + huafan[wWinner]) * (QzmjConstants.GAME_PLAYER - 1)) * wFanShu; // 赢三家
							// //
							// 庄家翻倍
			for (int play_index = 0; play_index < players.size(); play_index++) {
				if (play_index == wWinner)
					continue;
				Byte cur = new Byte((byte)play_index);
				player_index.remove(cur);
				Score[play_index] -= (QzmjConstants.Zhuang_Score + LianZzhuang_Count * QzmjConstants.Base_Score + kezi[wWinner] + goldfan[wWinner] + huafan[wWinner])
						* wFanShu - (kezi[play_index] + goldfan[play_index] + huafan[play_index]) * 2
						+ kezi[player_index.get(0)] + goldfan[player_index.get(0)] + huafan[player_index.get(0)]
						+kezi[player_index.get(1)] + goldfan[player_index.get(1)] + huafan[player_index.get(1)];
				player_index.add((byte)play_index);
			}
			mjround.setM_cbLianZhuangCount((byte) (LianZzhuang_Count + 1));

		} else {
			Score[wWinner] += (QzmjConstants.Base_Score*2+QzmjConstants.Zhuang_Score +LianZzhuang_Count * QzmjConstants.Base_Score +  (kezi[wWinner] + goldfan[wWinner] + huafan[wWinner])*(QzmjConstants.GAME_PLAYER - 1)) * wFanShu;// 闲家赢闲家
			for (int play_index = 0; play_index < players.size(); play_index++) {
				if (play_index == wWinner)
					continue;
				Byte cur = new Byte((byte)play_index);
				player_index.remove(cur);
				if (play_index == bankuser) {
					Score[bankuser] -= (QzmjConstants.Zhuang_Score+ LianZzhuang_Count * QzmjConstants.Base_Score + kezi[wWinner] + goldfan[wWinner] + huafan[wWinner])
							* wFanShu - (kezi[play_index] + goldfan[play_index] + huafan[play_index]) * 2
							+ kezi[player_index.get(0)] + goldfan[player_index.get(0)] + huafan[player_index.get(0)]
							+ kezi[player_index.get(1)] + goldfan[player_index.get(1)] + huafan[player_index.get(1)];
					player_index.add((byte)play_index);
					continue;
				}
				Score[play_index] -= (QzmjConstants.Base_Score + kezi[wWinner] + goldfan[wWinner] + huafan[wWinner])
						* wFanShu - (kezi[play_index] + goldfan[play_index] + huafan[play_index]) * 2
						+ kezi[player_index.get(0)] + goldfan[player_index.get(0)] + huafan[player_index.get(0)]
						+ kezi[player_index.get(1)] + goldfan[player_index.get(1)] + huafan[player_index.get(1)];
				player_index.add((byte)play_index);
			}
		//	mjround.setM_cbLianZhuangCount((byte) (1));
			short nextBankuser = (byte) (bankuser + 1);
			if (nextBankuser >= 4)
				nextBankuser = 0;// 地主转化
			mjround.setM_wBankerUser( nextBankuser);

			mjround.setM_cbLianZhuangCount((byte) 0);
		}
		List<TagAnalyseItem> analyses = mjround.getAnalyseItemArray();
		pushgame.card_eye = ChiHuCard;
		pushgame.socre = Score;
		pushgame.winner_index = (byte) wWinner;
		pushgame.Hu_type = Hu_type;
		pushgame.analyseitem = null;
		if (Hu_type == 5) {
			pushgame.analyseitem = null;
		} else if (Hu_type == 4 || Hu_type == 3 || Hu_type == 2) {
			AnalyseItem analyseitem = new AnalyseItem();
			for (TagAnalyseItem aAnaly : analyses) {
				if (!aAnaly.bMagicEye)
					continue;
				analyseitem.cbCardEye = aAnaly.cbCardEye;
				analyseitem.bMagicEye = 1;
				analyseitem.cbWeaveKind = aAnaly.cbWeaveKind;
				analyseitem.cbCenterCard = aAnaly.cbCenterCard;
				CbCardData cdb[] = new CbCardData[5];
				for (int size = 0; size < cdb.length; size++) {
					cdb[size] = new CbCardData();
					cdb[size].cards = aAnaly.cbCardData[size];
				}
				analyseitem.cbCardData = cdb;
				pushgame.analyseitem = analyseitem;
				break;
			}
		} else {
			TagAnalyseItem aAnaly = analyses.get(0);
			AnalyseItem analyseitem = new AnalyseItem();
			analyseitem.cbCardEye = aAnaly.cbCardEye;
			analyseitem.bMagicEye = 0;
			if (aAnaly.bMagicEye)
				analyseitem.bMagicEye = 1;
			analyseitem.cbWeaveKind = aAnaly.cbWeaveKind;
			analyseitem.cbCenterCard = aAnaly.cbCenterCard;
			CbCardData cdb[] = new CbCardData[5];
			for (int size = 0; size < cdb.length; size++) {
				cdb[size] = new CbCardData();
				cdb[size].cards = aAnaly.cbCardData[size];
			}
			analyseitem.cbCardData = cdb;
			pushgame.analyseitem = analyseitem;
		}
        ARound around = mjround.getARound();
        ARound.Builder modaround = around.toBuilder();
       
		for (int i = 0; i < players.size(); i++) {
			if (wWinner == i) {
				if (mjround.getM_wProvideUser() == wWinner)// 自摸
				{
					Zimo[i]++;
				} else {
					JiePao[i]++;// 胡
					DianPao[mjround.getM_wProvideUser()]++;// 放
				}

			}
			for (TagWeaveItem aweave : weavenItem[i]) {
				if (aweave.cbWeaveKind == 16) {
					if (aweave.wProvideUser == i)
						AnGang[i]++;
					else
						MingGang[i]++;
				}
			}
			PlayingRole pr = SessionManager.getInstance().getPlayer(players.get(i));
			if (pr != null && pr.isChannelActive()) {
				pr.writeAndFlush(pushgame.build(pr.alloc()));
			}
			modaround.addASocre(Score[i]);
			Sum_score[i] += Score[i];
		}
		ARound realround = modaround.build();
		mjround.setARound(realround);
        int room_type = RoomDataManager.getInstance().getRoomType(mjround.getPlayerIds().get(1));
		sendQzmjCalculatteHallServer(Score,mjround.getPlayerIds(),mjround.getGold_coin(),mjround.getRoomUuid(),mjround.getRound_count(),room_type);
		
		if((mjround.getCost_type()==0||mjround.getCost_type()==1)&&mjround.getFee()>0) {//房主结算或者AA结算
			sendQzmjCalculateFangka(mjround.getFee(),mjround.getCost_type(),mjround.getPlayerIds());
			mjround.setFee((short)0); //表示已经付钱
		}
		if(mjround.getIsYike()) {
			for(int i=0;i<Sum_score.length;i++) {
				if(Sum_score[i]<=0) {
					RoundOver(mjround);
					testRoundOver(mjround);
				}
			}
		}
		if (sumRound <= 0) {
			RoundOver(mjround);
			testRoundOver(mjround);
		}
		return false;
	}

	public void sendQzmjCalculateFangka(short fee,byte type,List<Integer> players) {
		String rsLanHost = RoomServer.getInstance().getServerConfig().getHallLanhost();
		int rsLanPort = RoomServer.getInstance().getServerConfig().getHallLanport();
		boolean reconnectRet = RoomServer.getInstance().getLanClientManager().connect(rsLanHost, rsLanPort);
		if(reconnectRet) {
			RoomServer.getInstance().getLanClientManager().sendCalculateFangKa(rsLanHost,rsLanPort, fee,type, players);
		}else {
			logger.error("connect 2 roomServer error!rsLanHost={},rsLanPort={}", rsLanHost, rsLanPort);
		}
	}
	
	public void sendQzmjCalculatteHallServer(short score[],List<Integer> players,int gold_coin,String roomid,short roundcount,int room_type) {
//		String rsLanHost = RoomServer.getInstance().getServerConfig().getHallLanhost();
//		
//		int rsLanPort = RoomServer.getInstance().getServerConfig().getHallLanport();
//		boolean reconnectRet = RoomServer.getInstance().getLanClientManager().connect(rsLanHost, rsLanPort);
//		if (reconnectRet) {
//			RoomServer.getInstance().getLanClientManager().sendCalculateHallServer(rsLanHost, rsLanPort,score, players,gold_coin,roomid,roundcount,room_type);
//		} else {
//			logger.error("connect 2 roomServer error!rsLanHost={},rsLanPort={}", rsLanHost, rsLanPort);
//		}
	}
	

	public byte jugde_HuaFan(List<Byte> Hualist) {
//		if (Hualist.size() == 8)
//			return 16;
//		byte[] cardsIndex = new byte[QzmjConstants.MAX_INDEX];
//		byte[] huacards = ArrayUtility.toByteArray(Hualist);
//		SwitchToCardIndex(huacards, (byte) Hualist.size(), cardsIndex);
//		if ((cardsIndex[38] + cardsIndex[39] + cardsIndex[40] + cardsIndex[41]) >= 4)
//			return 8;
//		if ((cardsIndex[34] + cardsIndex[35] + cardsIndex[36] + cardsIndex[37]) >= 4)
//			return 8;
		return (byte) Hualist.size();

	}

	public byte jugde_FanShu(final byte wWinner, QzmjRound mjround) {
		//boolean TiDihu[] = mjround.getM_bTianDiHu();
		boolean Single[] = mjround.getSingGold();
		boolean doublegold[] = mjround.getDoubleGold();
		boolean threegold[] = mjround.getThreeGold();
		byte cbCardIndex[][] = mjround.getCardIndex();
		byte wFanShu = 1;
//		if (!TiDihu[wWinner]) {
//			wFanShu = 4;
//			return wFanShu;
//		}
		if (IsSanJinDao(cbCardIndex[wWinner], mjround.getGod_card())&&mjround.isAllow_sanjindao()) {
			wFanShu = 3;
			return wFanShu;
		}
		if (threegold[wWinner]) {
			wFanShu = (byte) (mjround.getYoujin()*4);
			return wFanShu;
		}
		if (doublegold[wWinner]) {
			wFanShu = (byte) (mjround.getYoujin()*2);
			return wFanShu;
		}
		if (Single[wWinner]) {
			wFanShu = mjround.getYoujin();
			return wFanShu;
		}

		if (mjround.getM_wProvideUser() == wWinner) {
			wFanShu = 2;
			return wFanShu;
		}
		wFanShu = 1;
		return wFanShu;
	}

	public byte jugde_Hu_type(final byte wWinner, QzmjRound mjround) {
	//	boolean TiDihu[] = mjround.getM_bTianDiHu();
		boolean Single[] = mjround.getSingGold();
		boolean doublegold[] = mjround.getDoubleGold();
		boolean threegold[] = mjround.getThreeGold();
		byte cbCardIndex[][] = mjround.getCardIndex();
		byte Hu_type = 0;
//		if (!TiDihu[wWinner]) {
//			Hu_type = 1;
//			return Hu_type;
//		}
		if (IsSanJinDao(cbCardIndex[wWinner], mjround.getGod_card())&& mjround.isAllow_sanjindao()) {
			Hu_type = 5;
			return Hu_type;
		}
		if (threegold[wWinner]) {
			Hu_type = 4;
			return Hu_type;
		}
		if (doublegold[wWinner]) {
			Hu_type = 3;
			return Hu_type;
		}
		if (Single[wWinner]) {
			Hu_type = 2;
			return Hu_type;
		}

		if (mjround.getM_wProvideUser() == wWinner) {
			Hu_type = 0;
			return Hu_type;
		}
		Hu_type = 0;
		return Hu_type;
	}

	public void RoundOver(QzmjRound mjround) {

//		List<Integer> players = mjround.getPlayerIds();
//		for (Integer aPlayerId : players) {
//			QzmjDatamanager.getInstance().removePlayer(aPlayerId);
//		}
		// 全部对局结束的消息
		List<Integer> plays = mjround.getPlayerIds();
		PushQzmjRoundOver roundoverMsg = new PushQzmjRoundOver();
		roundoverMsg.score = mjround.getM_lGameScore();
		roundoverMsg.ZiMo = mjround.getZiMo();
		roundoverMsg.JiePao = mjround.getJiePao();
		roundoverMsg.DianPao = mjround.getDianPao();
		roundoverMsg.MingGang = mjround.getMingGang();
		roundoverMsg.AnGang = mjround.getAnGang();
		for (Integer aplay : plays) {
			PlayingRole pr = SessionManager.getInstance().getPlayer(aplay);
			if (pr != null && pr.isChannelActive()) {
				pr.writeAndFlush(roundoverMsg.build(pr.alloc()));
			}
		}
     //   testRoundOver(mjround);
		
	}

	public boolean RemoveCard(byte cbCardIndex[], byte[] cbRemoveCard, byte cbRemoveCount) {
		// 删除扑克
		for (byte i = 0; i < cbRemoveCount; i++) {
			// 效验扑克
			assert (IsValidCard(cbRemoveCard[i]));
			assert (cbCardIndex[SwitchToCardIndex(cbRemoveCard[i])] > 0);

			// 删除扑克
			byte cbRemoveIndex = SwitchToCardIndex(cbRemoveCard[i]);
			if (cbCardIndex[cbRemoveIndex] == 0) {
				// 错误断言
				assert (false);

				// 还原删除
				for (byte j = 0; j < i; j++) {
					assert (IsValidCard(cbRemoveCard[j]));
					cbCardIndex[SwitchToCardIndex(cbRemoveCard[j])]++;
				}

				return false;
			} else {
				// 删除扑克
				--cbCardIndex[cbRemoveIndex];
			}
		}

		return true;
	}

	// 删除一张扑克,按照转化为下标的扑克数组
	public boolean RemoveCard(byte cbCardIndex[], byte cbRemoveCard) {
		// 效验扑克
		assert (IsValidCard(cbRemoveCard));
		assert (cbCardIndex[SwitchToCardIndex(cbRemoveCard)] > 0);

		// 删除扑克
		byte cbRemoveIndex = SwitchToCardIndex(cbRemoveCard);
		if (cbCardIndex[cbRemoveIndex] > 0) {
			cbCardIndex[cbRemoveIndex]--;
			return true;
		}

		// 失败效验
		assert (false);

		return false;
	}

	public byte GetWeaveCard(byte cbWeaveKind, byte cbCenterCard, byte cbCardBuffer[]) {
		// 组合扑克
		switch (cbWeaveKind) {
		case QzmjConstants.WIK_LEFT: // 上牌操作
		{
			// 设置变量
			cbCardBuffer[0] = cbCenterCard;
			cbCardBuffer[1] = (byte) (cbCenterCard + 1);
			cbCardBuffer[2] = (byte) (cbCenterCard + 2);

			return 3;
		}
		case QzmjConstants.WIK_RIGHT: // 上牌操作
		{
			// 设置变量
			cbCardBuffer[0] = (byte) (cbCenterCard - 2);
			cbCardBuffer[1] = (byte) (cbCenterCard - 1);
			cbCardBuffer[2] = cbCenterCard;

			return 3;
		}
		case QzmjConstants.WIK_CENTER: // 上牌操作
		{
			// 设置变量
			cbCardBuffer[0] = (byte) (cbCenterCard - 1);
			cbCardBuffer[1] = cbCenterCard;
			cbCardBuffer[2] = (byte) (cbCenterCard + 1);

			return 3;
		}
		case QzmjConstants.WIK_PENG: // 碰牌操作
		{
			// 设置变量
			cbCardBuffer[0] = cbCenterCard;
			cbCardBuffer[1] = cbCenterCard;
			cbCardBuffer[2] = cbCenterCard;

			return 3;
		}
		case QzmjConstants.WIK_GANG: // 杠牌操作
		{
			// 设置变量
			cbCardBuffer[0] = cbCenterCard;
			cbCardBuffer[1] = cbCenterCard;
			cbCardBuffer[2] = cbCenterCard;
			cbCardBuffer[3] = cbCenterCard;

			return 4;
		}
		default: {
			assert (false);
		}
		}

		return 0;
	}

	public boolean AnalyseCard(final byte cbCardIndex[], final TagWeaveItem WeaveItem[], byte cbWeaveCount,
			List<TagAnalyseItem> AnalyseItemArray, byte god_card, QzmjRound mjround) {
		// 计算数目
		byte cbCardCount = GetCardCount(cbCardIndex);

		// 效验数目
		assert ((cbCardCount >= 2) && (cbCardCount <= QzmjConstants.MAX_COUNT) && ((cbCardCount - 2) % 3 == 0));
		if ((cbCardCount < 2) || (cbCardCount > QzmjConstants.MAX_COUNT) || ((cbCardCount - 2) % 3 != 0))
			return false;

		// 变量定义
		byte cbKindItemCount = 0;
		TagKindItem[] KindItem = mjround.getKindItem();
		ZeroMemory(KindItem);

		// 需求判断
		byte cbLessKindItem = (byte) ((cbCardCount - 2) / 3);
		assert ((cbLessKindItem + cbWeaveCount) == QzmjConstants.MAX_WEAVE);
		byte m_cbMagicIndex = SwitchToCardIndex(god_card);
		// 单吊判断
		if (cbLessKindItem == 0) {
			// 效验参数
			assert ((cbCardCount == 2) && (cbWeaveCount == QzmjConstants.MAX_WEAVE));
			// 牌眼判断
			for (byte i = 0; i < QzmjConstants.MAX_INDEX - QzmjConstants.MAX_HUA_CARD; i++) { // 091231JJ
				if (cbCardIndex[i] == 2 || (m_cbMagicIndex != QzmjConstants.MAX_INDEX && !IsMagicCard(i, true, god_card)
						&& GetMagicCardCount(cbCardIndex, m_cbMagicIndex) + cbCardIndex[i] == 2)) {
					// 变量定义
					TagAnalyseItem AnalyseItem = new TagAnalyseItem();
					// 设置结果
					for (byte j = 0; j < cbWeaveCount; j++) {
						AnalyseItem.cbWeaveKind[j] = WeaveItem[j].cbWeaveKind;
						AnalyseItem.cbCenterCard[j] = WeaveItem[j].cbCenterCard;
						// --------4自己写的-----
						System.arraycopy(WeaveItem[j].cbCardData, 0, AnalyseItem.cbCardData[j], 0, 4);
					}
					AnalyseItem.cbCardEye = SwitchToCardData(i);
					if (cbCardIndex[i] < 2 || IsMagicCard(i, true, god_card))
						AnalyseItem.bMagicEye = true;
					else
						AnalyseItem.bMagicEye = false;

					AnalyseItemArray.add(AnalyseItem);

					return true;
				}
			}

			return false;
		}

		// 拆分分析
		byte[] cbMagicCardIndex = new byte[QzmjConstants.MAX_INDEX];
		System.arraycopy(cbCardIndex, 0, cbMagicCardIndex, 0, QzmjConstants.MAX_INDEX);
		// 如果有财神
		byte cbMagicCardCount = 0;
		if (m_cbMagicIndex != QzmjConstants.MAX_INDEX) { // 091231JJ
															// 花牌财神
			cbMagicCardCount = GetMagicCardCount(cbMagicCardIndex, m_cbMagicIndex);
			// logger.info("huaCard yinggai ={}",cbMagicCardCount);
			// // 如果财神有代替牌，财神与代替牌转换
			// if (QzmjConstants.INDEX_REPLACE_CARD != QzmjConstants.MAX_INDEX) {
			// cbMagicCardIndex[m_cbMagicIndex] =
			// cbMagicCardIndex[QzmjConstants.INDEX_REPLACE_CARD];
			// cbMagicCardIndex[QzmjConstants.INDEX_REPLACE_CARD] = cbMagicCardCount;
			// }
		}
		if (cbCardCount >= 3) {
			for (byte i = 0; i < QzmjConstants.MAX_INDEX; i++) {
				if (i >= QzmjConstants.MAX_INDEX - QzmjConstants.MAX_HUA_CARD && i < QzmjConstants.MAX_INDEX
						&& !IsMagicCard(i, true, god_card))
					continue;

				// 同牌判断
				// 如果是财神,并且财神数小于3,则不进行组合
				if (cbMagicCardIndex[i] >= 3 || (cbMagicCardIndex[i] + cbMagicCardCount >= 3
						&& ((QzmjConstants.INDEX_REPLACE_CARD != QzmjConstants.MAX_INDEX
								&& i != cbMagicCardIndex[m_cbMagicIndex])))) {
					int nTempIndex = cbMagicCardIndex[i];
					do {
						assert (cbKindItemCount < KindItem.length);
						byte cbIndex = i;
						byte cbCenterCard = SwitchToCardData(i);
						// 如果是财神且财神有代替牌,则换成代替牌
						if (IsMagicCard(i, true, god_card)
								&& QzmjConstants.INDEX_REPLACE_CARD != QzmjConstants.MAX_INDEX) {
							// cbIndex = QzmjConstants.INDEX_REPLACE_CARD;
							// cbCenterCard = SwitchToCardData((byte) QzmjConstants.INDEX_REPLACE_CARD);
						}
						KindItem[cbKindItemCount].cbWeaveKind = QzmjConstants.WIK_PENG;
						KindItem[cbKindItemCount].cbCenterCard = cbCenterCard;
						KindItem[cbKindItemCount].cbValidIndex[0] = nTempIndex > 0 ? cbIndex : m_cbMagicIndex;
						KindItem[cbKindItemCount].cbValidIndex[1] = nTempIndex > 1 ? cbIndex : m_cbMagicIndex;
						KindItem[cbKindItemCount].cbValidIndex[2] = nTempIndex > 2 ? cbIndex : m_cbMagicIndex;
						cbKindItemCount++;

						// 如果是财神,则退出
						if (i == QzmjConstants.INDEX_REPLACE_CARD || (IsMagicCard(i, true, god_card)
								&& QzmjConstants.INDEX_REPLACE_CARD == QzmjConstants.MAX_INDEX))
							break;

						nTempIndex -= 3;
						// 如果刚好搭配全部，则退出
						if (nTempIndex == 0)
							break;

					} while (nTempIndex + cbMagicCardCount >= 3);
				}

				// 连牌判断
				if ((i < (QzmjConstants.MAX_INDEX - QzmjConstants.MAX_HUA_CARD - 9)) && ((i % 9) < 7)) {
					// 只要财神牌数加上3个顺序索引的牌数大于等于3,则进行组合
					if (cbMagicCardCount + cbMagicCardIndex[i] + cbMagicCardIndex[i + 1]
							+ cbMagicCardIndex[i + 2] >= 3) {
						byte[] cbIndex = new byte[] { cbMagicCardIndex[i], cbMagicCardIndex[i + 1],
								cbMagicCardIndex[i + 2] };
						int nMagicCountTemp = cbMagicCardCount;
						byte[] cbValidIndex = new byte[3];
						while (nMagicCountTemp + cbIndex[0] + cbIndex[1] + cbIndex[2] >= 3) {
							for (byte j = 0; j < cbIndex.length; j++) {
								if (cbIndex[j] > 0) {
									cbIndex[j]--;
								//	if (IsMagicCard((byte) (i + j), true, god_card))
								//		cbValidIndex[j] = QzmjConstants.INDEX_REPLACE_CARD;
							    //		else
										cbValidIndex[j] = (byte) (i + j);
								} else {
									nMagicCountTemp--;
									cbValidIndex[j] = m_cbMagicIndex;
								}
							}
							if (nMagicCountTemp >= 0) {
								assert (cbKindItemCount < KindItem.length);
								KindItem[cbKindItemCount].cbWeaveKind = QzmjConstants.WIK_LEFT;
								KindItem[cbKindItemCount].cbCenterCard = SwitchToCardData(i);
								System.arraycopy(cbValidIndex, 0, KindItem[cbKindItemCount].cbValidIndex, 0,
										cbValidIndex.length);
								cbKindItemCount++;
							} else
								break;
						}
					}
				}
			}
		}
		// int times = 0;
		// 组合分析
		if (cbKindItemCount >= cbLessKindItem) {
			// 变量定义
			byte[] cbCardIndexTemp = new byte[QzmjConstants.MAX_INDEX];
			byte[] cbIndex = new byte[QzmjConstants.MAX_WEAVE];
			for (byte i = 0; i < cbIndex.length; i++)
				cbIndex[i] = i;
			TagKindItem[] pKindItem = new TagKindItem[QzmjConstants.MAX_WEAVE];
			TagKindItem[] KindItemTemp = new TagKindItem[KindItem.length];
			if (m_cbMagicIndex != QzmjConstants.MAX_INDEX)
				System.arraycopy(KindItem, 0, KindItemTemp, 0, KindItem.length);

			// 开始组合
			do {
				// times++;
				System.arraycopy(cbCardIndex, 0, cbCardIndexTemp, 0, cbCardIndexTemp.length);
				cbMagicCardCount = 0;
				if (m_cbMagicIndex != QzmjConstants.MAX_INDEX) {
					System.arraycopy(KindItemTemp, 0, KindItem, 0, KindItem.length);
				}

				for (byte i = 0; i < cbLessKindItem; i++) {
					pKindItem[i] = new TagKindItem();
					pKindItem[i].cbCenterCard = KindItem[cbIndex[i]].cbCenterCard;
					pKindItem[i].cbWeaveKind = KindItem[cbIndex[i]].cbWeaveKind;
					pKindItem[i].cbValidIndex[0] = KindItem[cbIndex[i]].cbValidIndex[0];
					pKindItem[i].cbValidIndex[1] = KindItem[cbIndex[i]].cbValidIndex[1];
					pKindItem[i].cbValidIndex[2] = KindItem[cbIndex[i]].cbValidIndex[2];
				}
				// = KindItem[cbIndex[i]];

				// 数量判断
				boolean bEnoughCard = true;
				for (byte i = 0; i < cbLessKindItem * 3; i++) {
					// 存在判断
					byte cbCardIndex1 = pKindItem[i / 3].cbValidIndex[i % 3];
					if (cbCardIndexTemp[cbCardIndex1] == 0) {
						if (m_cbMagicIndex != QzmjConstants.MAX_INDEX
								&& GetMagicCardCount(cbCardIndexTemp, m_cbMagicIndex) > 0) {
							for (int k = 0; k < QzmjConstants.MAX_INDEX; k++) {
								if (cbCardIndexTemp[k] > 0 && IsMagicCard((byte) k, true, god_card)) {
									cbCardIndexTemp[k]--;
									pKindItem[i / 3].cbValidIndex[i % 3] = (byte) k;
								}
							}
						} else {
							bEnoughCard = false;
							break;
						}
					} else
						cbCardIndexTemp[cbCardIndex1]--;
				}

				// 胡牌判断
				if (bEnoughCard == true) {
					// 牌眼判断
					byte cbCardEye = 0;
					boolean bMagicEye = false;
					if (GetCardCount(cbCardIndexTemp) == 2) {
						for (byte i = 0; i < QzmjConstants.MAX_INDEX - QzmjConstants.MAX_HUA_CARD; i++) { // 091231JJ
							byte cards[] = new byte[5];
							SwitchToCardData(cbCardIndexTemp, cards);
							if (cbIndex[0] == 1 && cbIndex[1] == 7 && cbIndex[2] == 13 && cbIndex[3] == 17
									&& cbIndex[4] == 23) {
								/// logger.info("eye cards={}", cards);
								// logger.info("cbCardIndexTemp",cbCardIndexTemp);
							}
							// 胡牌牌眼判断
							if (cbCardIndexTemp[i] == 2) {
								cbCardEye = SwitchToCardData(i);
								if (m_cbMagicIndex != QzmjConstants.MAX_INDEX && IsMagicCard(i, true, god_card))
									bMagicEye = true;
								break;
							} else if (GetMagicCardCount(cbCardIndexTemp, m_cbMagicIndex) == 2) {
								cbCardEye = SwitchToCardData(m_cbMagicIndex);
								bMagicEye = true;
								break;
							} else if (!IsMagicCard(i, true, god_card) && m_cbMagicIndex != QzmjConstants.MAX_INDEX
									&& cbCardIndexTemp[i] + GetMagicCardCount(cbCardIndexTemp, m_cbMagicIndex) == 2) {
								cbCardEye = SwitchToCardData(i);
								bMagicEye = true;
								break;
							}
						}
					}

					// 组合类型
					if (cbCardEye != 0) {
						// 变量定义
						TagAnalyseItem AnalyseItem = new TagAnalyseItem();
						// 设置组合
						for (byte i = 0; i < cbWeaveCount; i++) {
							AnalyseItem.cbWeaveKind[i] = WeaveItem[i].cbWeaveKind;
							AnalyseItem.cbCenterCard[i] = WeaveItem[i].cbCenterCard;
							GetWeaveCard(WeaveItem[i].cbWeaveKind, WeaveItem[i].cbCenterCard,
									AnalyseItem.cbCardData[i]);
						}

						// 设置牌型
						for (byte i = 0; i < cbLessKindItem; i++) {
							AnalyseItem.cbWeaveKind[i + cbWeaveCount] = pKindItem[i].cbWeaveKind;
							AnalyseItem.cbCenterCard[i + cbWeaveCount] = pKindItem[i].cbCenterCard;
							AnalyseItem.cbCardData[cbWeaveCount + i][0] = SwitchToCardData(
									pKindItem[i].cbValidIndex[0]);
							AnalyseItem.cbCardData[cbWeaveCount + i][1] = SwitchToCardData(
									pKindItem[i].cbValidIndex[1]);
							AnalyseItem.cbCardData[cbWeaveCount + i][2] = SwitchToCardData(
									pKindItem[i].cbValidIndex[2]);
						}

						// 设置牌眼
						AnalyseItem.cbCardEye = cbCardEye;
						AnalyseItem.bMagicEye = bMagicEye;

						// 插入结果
						AnalyseItemArray.add(AnalyseItem);
						if(GetMagicCardCount(cbMagicCardIndex, m_cbMagicIndex)>2) {
							return (AnalyseItemArray.size() > 0);
						}
						
					}
				}

				// 设置索引
				if (cbIndex[cbLessKindItem - 1] == (cbKindItemCount - 1)) {
					byte i = (byte) (cbLessKindItem - 1);
					for (; i > 0; i--) {
						if ((cbIndex[i - 1] + 1) != cbIndex[i]) {
							byte cbNewIndex = cbIndex[i - 1];
							for (byte j = (byte) (i - 1); j < cbLessKindItem; j++)
								cbIndex[j] = (byte) (cbNewIndex + j - i + 2);
							break;
						}
					}
					if (i == 0)
						break;
				} else
					cbIndex[cbLessKindItem - 1]++;
			} while (true);

		}
		// logger.info("分析组合========={}",times);
		return (AnalyseItemArray.size() > 0);
	}

	public boolean IsSanJinDao(byte cbCardIndex[], byte god_card) {

		byte m_cbMagicIndex = SwitchToCardIndex(god_card);
		// 无财神不算
		if (m_cbMagicIndex == QzmjConstants.MAX_INDEX)
			return false;

		byte bMagicCardCount = GetMagicCardCount(cbCardIndex, m_cbMagicIndex);

		if (bMagicCardCount >= 3)
			return true;

		else
			return false;

	}

	// 获得花牌的数目
	public static byte GetMagicCardCount(final byte cbCardIndex[], byte m_cbMagicIndex) {
		if (m_cbMagicIndex >= QzmjConstants.MAX_INDEX)
			return 0;
		if (m_cbMagicIndex >= 0 && m_cbMagicIndex < QzmjConstants.MAX_INDEX - QzmjConstants.MAX_HUA_CARD)
			return cbCardIndex[m_cbMagicIndex];
		// 不会出现 翻到花牌应该会继续往下翻与温州麻将有区别
		byte cbMagicCardCount = 0;
		if (m_cbMagicIndex >= QzmjConstants.MAX_INDEX - QzmjConstants.MAX_HUA_CARD
				&& m_cbMagicIndex < QzmjConstants.MAX_INDEX - QzmjConstants.MAX_HUA_CARD + 4)
			cbMagicCardCount = (byte) (cbCardIndex[34] + cbCardIndex[35] + cbCardIndex[36] + cbCardIndex[37]);
		else if (m_cbMagicIndex >= QzmjConstants.MAX_INDEX - QzmjConstants.MAX_HUA_CARD + 4
				&& m_cbMagicIndex < QzmjConstants.MAX_INDEX)
			cbMagicCardCount = (byte) (cbCardIndex[38] + cbCardIndex[39] + cbCardIndex[40] + cbCardIndex[41]);
		else
			assert (false);

		return cbMagicCardCount;
	}

	public static void FiltrateRight(int wWinner, CChiHuRight chr, QzmjRound mjround) {
		boolean m_bTianDiHu[] = mjround.getM_bTianDiHu();
		/* 增加权位 */
		int m_wProvideUser = mjround.getM_wProvideUser();
		int m_wBankerUser = mjround.getM_wBankerUser();
		// 自摸
		if (wWinner == m_wProvideUser) {
			chr.HuoFuzhi(QzmjConstants.CHR_ZI_MO);// chr |= MjConstants.CHR_ZI_MO;
			chr.HuoFuzhi(QzmjConstants.CHR_YING_HU);// chr |=
													// MjConstants.CHR_YING_HU;
		}

		// 天地胡
		if (!m_bTianDiHu[wWinner]) {
			if (wWinner == m_wBankerUser)
				chr.HuoFuzhi(QzmjConstants.CHR_TIAN_HU);// chr |=
														// MjConstants.CHR_TIAN_HU;
			else
				chr.HuoFuzhi(QzmjConstants.CHR_DI_HU);// chr |=
														// MjConstants.CHR_DI_HU;
		}

		if (!chr.Yu(QzmjConstants.CHR_BA_DUI_YING).IsEmpty())
			if (!(chr.Yu(QzmjConstants.CHR_BA_DUI_YING).IsEmpty()))
				chr.YuFuzhi(~QzmjConstants.CHR_BA_DUI);

		// 双翻不计硬胡 软胡
		if (!chr.Yu(QzmjConstants.CHR_BA_DUI_YING).IsEmpty() || !chr.Yu(QzmjConstants.CHR_THREE_KING).IsEmpty()
				|| !chr.Yu(QzmjConstants.CHR_TIAN_HU).IsEmpty() || !chr.Yu(QzmjConstants.CHR_DI_HU).IsEmpty()
				|| !chr.Yu(QzmjConstants.CHR_DAN_DIAO).IsEmpty()) {
			chr.HuoFuzhi(QzmjConstants.CHR_SHUANG_FAN);// chr |=
														// MjConstants.CHR_SHUANG_FAN;
			chr.YuFuzhi(~QzmjConstants.CHR_YING_HU);
			chr.YuFuzhi(~QzmjConstants.CHR_RUAN_HU);// chr &=
													// ~MjConstants.CHR_RUAN_HU;
		}

		else if (!chr.Yu(QzmjConstants.CHR_YING_HU).IsEmpty()) // 硬胡不计软胡
			chr.YuFuzhi(~QzmjConstants.CHR_RUAN_HU);// chr &=
													// ~MjConstants.CHR_RUAN_HU;
		else
			chr.HuoFuzhi(QzmjConstants.CHR_RUAN_HU);// chr |=
													// MjConstants.CHR_RUAN_HU;
	}

	public byte AnalyseGangCard(final byte cbCardIndex[], final TagWeaveItem WeaveItem[], byte cbWeaveCount,
			TagGangCardResult GangCardResult, byte godCard) {
		// 设置变量
		byte cbActionMask = QzmjConstants.WIK_NULL;
		byte m_cbMagicIndex = SwitchToCardData(godCard);
		GangCardResult.cbCardCount = 0;
		for (int i = 0; i < GangCardResult.cbCardData.length; i++) {
			GangCardResult.cbCardData[i] = 0;
		}
		// ZeroMemory(&GangCardResult,sizeof(GangCardResult));
		// 手上杠牌
		for (byte i = 0; i < QzmjConstants.MAX_INDEX; i++) {
			if (i == m_cbMagicIndex)
				continue;
			if (cbCardIndex[i] == 4) {
				cbActionMask |= QzmjConstants.WIK_GANG;
				GangCardResult.cbCardData[GangCardResult.cbCardCount++] = SwitchToCardData(i);
			}
		}

		// 组合杠牌
		for (byte i = 0; i < cbWeaveCount; i++) {
			if (WeaveItem[i].cbWeaveKind == QzmjConstants.WIK_PENG) {
				if (cbCardIndex[SwitchToCardIndex(WeaveItem[i].cbCenterCard)] == 1) {
					cbActionMask |= QzmjConstants.WIK_GANG;
					GangCardResult.cbCardData[GangCardResult.cbCardCount++] = WeaveItem[i].cbCenterCard;
				}
			}
		}

		return cbActionMask;
	}

	public byte SwitchToCardIndex(final byte cbCardData[], byte cbCardCount, byte cbCardIndex[]) {
		// 转换扑克
		for (Byte i = 0; i < cbCardCount; i++) {
			if (cbCardData[i] == 0)
				continue;// 这个手牌中存在0值;
			cbCardIndex[SwitchToCardIndex(cbCardData[i])]++;
		}

		return cbCardCount;
	}

	public byte SwitchToCardIndex(Byte cbCardData) {
		assert (IsValidCard(cbCardData));
		byte retByte = (byte) (((cbCardData & QzmjConstants.MASK_COLOR) >> 4) * 9
				+ (cbCardData & QzmjConstants.MASK_VALUE) - 1);
		return retByte;
	}

	public boolean IsValidCard(Byte cbCardData) {
		Byte cbValue = (byte) (cbCardData & QzmjConstants.MASK_VALUE);
		Byte cbColor = (byte) ((cbCardData & QzmjConstants.MASK_COLOR) >> 4);
		return (((cbValue >= 1) && (cbValue <= 9) && (cbColor <= 2))
				|| ((cbValue >= 1) && (cbValue <= 0x0f) && (cbColor == 3)));
	}

	public byte SwitchToCardData(final byte cbCardIndex[], byte cbCardData[]) {
		// byte m_cbMagicIndex = SwitchToCardIndex(mjround.getGod_card());
		// 转换扑克
		byte cbPosition = 0;
		// 钻牌
		/*
		 * if (m_cbMagicIndex != MjConstants.MAX_INDEX) { // 091231JJ
		 * 
		 * if (m_cbMagicIndex >= MjConstants.MAX_INDEX - MjConstants.MAX_HUA_CARD&&
		 * m_cbMagicIndex < MjConstants.MAX_INDEX) { for (int i = MjConstants.MAX_INDEX
		 * - MjConstants.MAX_HUA_CARD; i < MjConstants.MAX_INDEX; i++) { if
		 * (cbCardIndex[i] > 0 && IsMagicCard((byte) i, true, mjround.getGod_card()))
		 * cbCardData[cbPosition++] = SwitchToCardData((byte) i); } } else { for (byte i
		 * = 0; i < cbCardIndex[m_cbMagicIndex]; i++) cbCardData[cbPosition++] =
		 * SwitchToCardData(m_cbMagicIndex);//有金牌 首先提出金牌 } }
		 * 
		 * for (byte i = 0; i < MjConstants.MAX_INDEX; i++) { if (IsMagicCard(i, true,
		 * mjround.getGod_card()) && (m_cbMagicIndex != MjConstants.INDEX_REPLACE_CARD))
		 * { // 如果财神有代替牌，则代替牌代替财神原来的位置 if (MjConstants.INDEX_REPLACE_CARD !=
		 * MjConstants.MAX_INDEX) { for (byte j = 0; j <
		 * cbCardIndex[MjConstants.INDEX_REPLACE_CARD]; j++) cbCardData[cbPosition++] =
		 * SwitchToCardData((byte) MjConstants.INDEX_REPLACE_CARD); } continue; } if (i
		 * == MjConstants.INDEX_REPLACE_CARD) continue; if(i == m_cbMagicIndex )
		 * continue; if (cbCardIndex[i] != 0) { for (byte j = 0; j < cbCardIndex[i];
		 * j++) { assert (cbPosition < MjConstants.MAX_COUNT); cbCardData[cbPosition++]
		 * = SwitchToCardData(i); } } }
		 */
		for (byte i = 0; i < QzmjConstants.MAX_INDEX; i++) {
			// if (IsMagicCard(i, true, mjround.getGod_card()) && (m_cbMagicIndex !=
			// MjConstants.INDEX_REPLACE_CARD)) {
			// // 如果财神有代替牌，则代替牌代替财神原来的位置
			// if (MjConstants.INDEX_REPLACE_CARD != MjConstants.MAX_INDEX) {
			// for (byte j = 0; j < cbCardIndex[MjConstants.INDEX_REPLACE_CARD]; j++)
			// // cbCardData[cbPosition++] = SwitchToCardData((byte)
			// MjConstants.INDEX_REPLACE_CARD);
			// }
			// continue;
			// }
			// if (i == MjConstants.INDEX_REPLACE_CARD)
			// continue;
			// if(i == m_cbMagicIndex )
			// continue;
			if (cbCardIndex[i] != 0) {
				for (byte j = 0; j < cbCardIndex[i]; j++) {
					assert (cbPosition < QzmjConstants.MAX_COUNT);
					cbCardData[cbPosition++] = SwitchToCardData(i);
				}
			}
		}

		return cbPosition;
	}

	public static byte SwitchToCardData(byte cbCardIndex) {
		assert (cbCardIndex < QzmjConstants.MAX_INDEX);
		byte card_data = 0;
		if (cbCardIndex < 27)
			card_data = (byte) (((cbCardIndex / 9) << 4) | (cbCardIndex % 9 + 1));
		else
			card_data = (byte) (0x30 | (cbCardIndex - 27 + 1));
		return card_data;
	}

	public boolean SendOperateNotify(QzmjRound mjround, byte cbCenterCard) {
		// logger.info("sendoperate action notice");
		byte[] useraction = mjround.getM_cbUserAction();
		List<Integer> playerIds = mjround.getPlayerIds();
		PushQzmjUserAction pushmjaction = new PushQzmjUserAction();
		pushmjaction.out_card = cbCenterCard;
		logger.info("reget------action={}", useraction);
		int i = 0;
		for (Integer aPlayerId : playerIds) {
			if (useraction[i] == 0) {
				i++;
				continue;
			}

			PlayingRole pr = SessionManager.getInstance().getPlayer(aPlayerId);

			pushmjaction.action = useraction[i];

			if (pr != null && pr.isChannelActive()) {
				pr.writeAndFlush(pushmjaction.build(pr.alloc()));
				// 推送关于出牌的信息
			}
			i++;
		}
		return false;

	}

	public void mjStart(Channel channel, String roomId, List<QzmjLanPlayerInfo> playerList, short roundSum, byte sanjin,
			byte eat_card, byte hua_card, byte prevent, int gold_coin,byte cost_type,byte youjin,short fee,Map<Integer,String> ipmap) {
		logger.info("mj start,playerList={},roundSum={}", playerList, roundSum);
		int playerCount = playerList.size();
		QzmjRound mjRound = new QzmjRound();
		if (sanjin == 1)
			mjRound.setAllow_sanjindao(true);
		if (eat_card == 1)
			mjRound.setAllow_eatcard(true);
		if (hua_card == 1)
			mjRound.setAllow_hua(true);
		if (prevent == 1)
			mjRound.setPrevent_cheat(true);
		if (gold_coin >= 0)
			mjRound.setGold_coin(gold_coin);
		mjRound.setIpmaps(ipmap);
		mjRound.setCost_type(cost_type);
		mjRound.setYoujin(youjin);
		mjRound.setFee(fee);
		mjRound.setGamestart(false);// 游戏未开始
		mjRound.setM_wReplaceUser(QzmjConstants.INVALID_CHAIR);// 不可获得
		mjRound.setCardIndex(new byte[4][QzmjConstants.MAX_INDEX]);
		mjRound.setM_lGameScore(new short[4]); // 设置一个的得分数组
		mjRound.setM_bTrustee(new boolean[4]); // 设置一个判断是否托管
		// aRound.setM_cbListenStatus(new byte[4]); // 听牌
		Set<Integer> enter_player = new HashSet<>();
		mjRound.setEnter_player(enter_player);
		mjRound.setM_bTianDiHu(new boolean[4]); // 天胡状态
		mjRound.setM_cbFengCardData(new byte[4]); // 记录蜂派
		mjRound.setM_bEnjoinChiHu(new boolean[4]); // 禁止吃胡
		mjRound.setM_bEnjoinChiPeng(new boolean[4]); // 禁止吃碰
		mjRound.setM_bResponse(new boolean[4]); // 响应标志
		mjRound.setM_cbUserAction(new byte[4]);// 用户动作
		mjRound.setM_cbOperateCard(new byte[4][4]); // 操作扑克
		mjRound.setM_cbPerformAction(new byte[4]); // 执行动作
		mjRound.setM_cbWeaveItemCount(new byte[4]); // 组合数目
		mjRound.setM_cbOutCardCount(0); // 出牌数目
		mjRound.setM_cbSendCardData(0); // 发牌的扑克
		mjRound.setCards(new byte[QzmjConstants.GAME_PLAYER][17]); // 牌
		mjRound.setM_cbSendCardData(0); // 发牌的扑克
		mjRound.setGenFeng(new boolean[4]); // 跟大牌
		mjRound.setPlayReady(new boolean[4]); // 设置玩家准状态
		mjRound.setM_cbLianZhuangCount((byte) 0); // 设置庄家连庄
		mjRound.setZiMo(new byte[4]); // 自摸次数
		mjRound.setJiePao(new byte[4]);// 接炮
		mjRound.setDianPao(new byte[4]);// 点炮
		mjRound.setMingGang(new byte[4]);// 明杠
		mjRound.setAnGang(new byte[4]);// 暗杠
		mjRound.setVotediss(new boolean[4]); //投票解散
		mjRound.setSingGold(new boolean[4]); // 单游
		mjRound.setDoubleGold(new boolean[4]); // 双游
		mjRound.setThreeGold(new boolean[4]); // 三游
		mjRound.setSanJingDao(new boolean[4]);// 三金倒
		if(roundSum>=60) {
			//mjRound.setM_lGameScore(new short[4]); // 设置一个的得分数组
			short socre[] = mjRound.getM_lGameScore();
			for(int i=0;i<socre.length;i++)
				socre[i] = 100;
			mjRound.setIsYike(true);
			
		}
		long create_time = System.currentTimeMillis() / 1000;
		mjRound.setCreate_time((int) create_time); // 创建时间

		List<List<Byte>> pushed_card = new ArrayList<>(); // 打出的牌
		for (int i = 0; i < 4; i++) {
			List<Byte> aplaycard = new ArrayList<>();
			pushed_card.add(aplaycard);
		}
		mjRound.setPushed_card(pushed_card);
		List<List<Byte>> singgold = new ArrayList<>();
		for (int i = 0; i < 4; i++) {
			List<Byte> Aplay = new ArrayList<>();
			singgold.add(Aplay);
		}
		mjRound.setSingCardEye(singgold); // 单游牌眼
		List<List<Byte>> doublegold = new ArrayList<>();
		for (int i = 0; i < 4; i++) {
			List<Byte> Aplay = new ArrayList<>();
			doublegold.add(Aplay);
		}
		mjRound.setDoubleCardEye(doublegold);// 双游牌眼
		TagKindItem[] kinditem = new TagKindItem[27 * 2 + 28];
		for (int i = 0; i < 27 * 2 + 28; i++) {
			kinditem[i] = new TagKindItem();
		}
		mjRound.setKindItem(kinditem);
		List<TagAnalyseItem> TagAnalyseItem = new ArrayList<>();
		mjRound.setAnalyseItemArray(TagAnalyseItem);
		// mjRound.setM_cbChiHuCard();
		List<Byte> remain_card = new LinkedList<>();
		mjRound.setRemain_card(remain_card);
		TagWeaveItem[][] tagWeaveItem = new TagWeaveItem[4][5];
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 5; j++) {
				tagWeaveItem[i][j] = new TagWeaveItem();
				tagWeaveItem[i][j].cbCardData = new byte[4];
			}
		}
		mjRound.setM_WeaveItemArray(tagWeaveItem);
		mjRound.setM_dwChiHuKind(new byte[4]); // 吃胡结果
		CChiHuRight[] CChiHuRight = new CChiHuRight[4];
		for (int i = 0; i < 4; i++) {
			CChiHuRight[i] = new CChiHuRight();
		}
		mjRound.setM_ChiHuRight(CChiHuRight); // 吃胡权位
		mjRound.setRoundSum(roundSum);
		mjRound.setRound_count(roundSum);// 总局数量
		mjRound.setRoomUuid(roomId);

		QzmjStar2HsMessage respMsg = new QzmjStar2HsMessage(channel.alloc());
		respMsg.writeString(roomId);
		respMsg.writeInt(playerCount);
		short[] Shaizi_num = new short[2];
		Shaizi_num[0] = (short) RandomUtils.nextInt(1, 7);
		Shaizi_num[1] = (short) RandomUtils.nextInt(1, 7);
		//short location = (short) (Shaizi_num[0] + Shaizi_num[1]);
	//	mjRound.setM_wCurrentUser(QzmjConstants.location[location]); // 当前出牌玩家
	//	mjRound.setM_wBankerUser(QzmjConstants.location[location]); // 当前庄家
		mjRound.setM_wCurrentUser(0); // 当前出牌玩家
		mjRound.setM_wBankerUser((byte)0); // 当前庄家
		randCard(mjRound);// 手牌发送
		byte[][] aPlayerCards = mjRound.getCards();
		for (int i = 0; i < playerCount; i++) {
			int playerId = playerList.get(i).getPlayerId();
			byte[] aplayercard = aPlayerCards[i];
			respMsg.writeInt(playerId);
			respMsg.writeInt(aplayercard.length);
			for (byte aCard : aplayercard) {
				respMsg.writeByte(aCard);
			}
		}
		respMsg.writeShort(Shaizi_num[0]);
		respMsg.writeShort(Shaizi_num[1]);
		// 缓存玩家信息
		List<Integer> playerIds = new ArrayList<>();
		mjRound.setPlayerIds(playerIds);
		for (QzmjLanPlayerInfo MjLanPlayerInfo : playerList) {
			LanSessionCache.getInstance().addSession(MjLanPlayerInfo.getSessionId(), MjLanPlayerInfo.getPlayerId());
			playerIds.add(MjLanPlayerInfo.getPlayerId());
		}
		// 缓存牌局的信息
		for (QzmjLanPlayerInfo ddzLanPlayerInfo : playerList) {
			QzmjDatamanager.getInstance().addRoundCache(ddzLanPlayerInfo.getPlayerId(), mjRound);
		}
		AllRound.Builder  allround = AllRound.newBuilder();
		allround.setIsSanjindao(sanjin);
		allround.setDanOrtongpei(1);
		allround.setEatCard(eat_card);
		allround.setHuaCard(hua_card);
		allround.setGoldRate(gold_coin);
		allround.setFeeCost(cost_type);
		allround.setCountNum(roundSum);
		allround.setRoomId(mjRound.getRoomUuid());
		allround.setRoomtype(5);
		for(Integer player:playerIds) {
			PlayerBean poc = RoomDataManager.getInstance().getPlayerBean(player);
			AllPlayers.Builder gameplayer = AllPlayers.newBuilder();
			gameplayer.setPlayerId(player);
			gameplayer.setName(poc.getName());
			gameplayer.setSex(poc.getSex());
			gameplayer.setHeading(poc.getHeadimg());
			long jindou = poc.getJindou();
			gameplayer.setJindou((int)jindou);
			AllPlayers play = gameplayer.build();
			allround.addPlayers(play);	
		}
		AllRound real = allround.build();
		mjRound.setAllround(real);
		
		channel.writeAndFlush(respMsg);
	}
	
	public void randCard(QzmjRound aRound) {
		byte[] cbCardBuffer;
		int cbBufferCount;
		byte[] cbCardData;
		if (aRound.isAllow_hua()) {
			// 混乱准备
			cbCardBuffer = new byte[QzmjConstants.cardData.length];
			cbBufferCount = (int) cbCardBuffer.length;
			cbCardData = Arrays.copyOf(QzmjConstants.cardData, QzmjConstants.cardData.length);
			// 混乱扑克
			int bRandCount = 0, bPosition = 0;
			do {
				bPosition = (int) (RandomUtils.nextInt(0, Integer.MAX_VALUE)
						% (QzmjConstants.cardData.length - bRandCount));
				cbCardBuffer[bRandCount++] = cbCardData[bPosition];
				cbCardData[bPosition] = cbCardData[QzmjConstants.cardData.length - bRandCount];
			} while (bRandCount < cbBufferCount);
			// 随机玩家手牌
		} else {
			// 混乱准备
			cbCardBuffer = new byte[QzmjConstants.cardData_not_hua.length];
			cbBufferCount = (int) cbCardBuffer.length;
			cbCardData = Arrays.copyOf(QzmjConstants.cardData_not_hua, QzmjConstants.cardData_not_hua.length);
			// 混乱扑克
			int bRandCount = 0, bPosition = 0;
			do {
				bPosition = (int) (RandomUtils.nextInt(0, Integer.MAX_VALUE)
						% (QzmjConstants.cardData_not_hua.length - bRandCount));
				cbCardBuffer[bRandCount++] = cbCardData[bPosition];
				cbCardData[bPosition] = cbCardData[QzmjConstants.cardData_not_hua.length - bRandCount];
			} while (bRandCount < cbBufferCount);
		}
		byte[][] shoupai = aRound.getCards();
		ZeroMemory(shoupai); // 清空手牌
		for (int i = 0; i < QzmjConstants.GAME_PLAYER; i++) {
			List<Byte> array_card = new ArrayList<>();
			for (int j = 0 + 16 * i; j < 16 * (i + 1); j++) {
				array_card.add(cbCardBuffer[j]);
			}
			array_card.add((byte) 0);
			byte[] aPlayerCards = ArrayUtility.toByteArray(array_card);

			shoupai[i] = aPlayerCards;
		}
		aRound.setCards(shoupai);
		List<Byte> remain_card = aRound.getRemain_card();
		remain_card.clear();
		for (int i = 64; i < cbBufferCount; i++) {
			remain_card.add(cbCardBuffer[i]);
		}

		aRound.setRemain_card(remain_card);
		return;
	}
	public void randCard_test(QzmjRound aRound) {
		byte[] cbCardBuffer;
		int cbBufferCount;
		byte[] cbCardData;
		if (aRound.isAllow_hua()) {
			// 混乱准备
			cbCardBuffer = new byte[QzmjConstants.cardData.length];
			cbBufferCount = (int) cbCardBuffer.length;
			cbCardData = Arrays.copyOf(QzmjConstants.cardData, QzmjConstants.cardData.length);
			// 混乱扑克
			int bRandCount = 0, bPosition = 0;
			do {
				bPosition = (int) (RandomUtils.nextInt(0, Integer.MAX_VALUE)
						% (QzmjConstants.cardData.length - bRandCount));
				cbCardBuffer[bRandCount++] = cbCardData[bPosition];
				cbCardData[bPosition] = cbCardData[QzmjConstants.cardData.length - bRandCount];
			} while (bRandCount < cbBufferCount);
			// 随机玩家手牌
		} else {
			// 混乱准备
			cbCardBuffer = new byte[QzmjConstants.cardData_not_hua.length];
			cbBufferCount = (int) cbCardBuffer.length;
			cbCardData = Arrays.copyOf(QzmjConstants.cardData_not_hua, QzmjConstants.cardData_not_hua.length);
			// 混乱扑克
			int bRandCount = 0, bPosition = 0;
			do {
				bPosition = (int) (RandomUtils.nextInt(0, Integer.MAX_VALUE)
						% (QzmjConstants.cardData_not_hua.length - bRandCount));
				cbCardBuffer[bRandCount++] = cbCardData[bPosition];
				cbCardData[bPosition] = cbCardData[QzmjConstants.cardData_not_hua.length - bRandCount];
			} while (bRandCount < cbBufferCount);
		}
		byte[][] shoupai = aRound.getCards();
		ZeroMemory(shoupai); // 清空手牌
		for (int i = 0; i < QzmjConstants.GAME_PLAYER; i++) {
			List<Byte> array_card = new ArrayList<>();
			for (int j = 0 + 16 * i; j < 16 * (i + 1); j++) {
				array_card.add(cbCardBuffer[j]);
			}
			array_card.add((byte) 0);
			byte[] aPlayerCards = ArrayUtility.toByteArray(array_card);

			shoupai[i] = aPlayerCards;
		}
		shoupai[0][0] = 1; shoupai[0][1] = 2; shoupai[0][2] = 3;
		shoupai[0][3] = 7; shoupai[0][4] = 8; shoupai[0][5] = 9;
		shoupai[0][6] = 33; shoupai[0][7] = 34; shoupai[0][8] = 35;
		shoupai[0][9] = 20; shoupai[0][10] = 20; shoupai[0][11] = 20;
		shoupai[0][12] = 39; shoupai[0][13] = 40; shoupai[0][14] = 41;
		shoupai[0][15] = 41;
		
		shoupai[1][0] = 1; shoupai[1][1] = 2; shoupai[1][2] = 3;
		shoupai[1][3] = 7; shoupai[1][4] = 8; shoupai[1][5] = 9;
		shoupai[1][6] = 33; shoupai[1][7] = 34; shoupai[1][8] = 35;
		shoupai[1][9] = 20; shoupai[1][10] = 20; shoupai[1][11] = 20;
		shoupai[1][12] = 39; shoupai[1][13] = 40; shoupai[1][14] = 41;
		shoupai[1][15] = 41;
		
//		aRound.setCards(shoupai);
//		List<Byte> remain_card = aRound.getRemain_card();
//		remain_card.clear();
//		for (int i = 64; i < cbBufferCount; i++) {
//			remain_card.add(cbCardBuffer[i]);
//		}
		List<Byte> remain_card = aRound.getRemain_card();
		remain_card.clear();
		for (int i = 64; i < cbBufferCount; i++) {
			remain_card.add(cbCardBuffer[i]);
		}

		aRound.setRemain_card(remain_card);
		return;
	}

	public static void ZeroMemory(TagKindItem[] tag) {
		for (int i = 0; i < tag.length; i++) {
			tag[i].cbCenterCard = 0;
			tag[i].cbWeaveKind = 0;
			ZeroMemory(tag[i].cbValidIndex);
		}
	}

	public static void ZeroMemory(byte[][] array) {
		for (byte i = 0; i < array.length; i++) {
			for (byte j = 0; j < array[i].length; j++) {
				array[i][j] = 0;
			}
		}
	}

	public static void ZeroMemory(byte[] array) {
		for (int i = 0; i < array.length; i++) {
			array[i] = 0;
		}
	}

	public static void ZeroMemory(int[] array) {
		for (int i = 0; i < array.length; i++) {
			array[i] = 0;
		}
	}

	public static void ZeroMemory(boolean[] array) {
		for (int i = 0; i < array.length; i++) {
			array[i] = false;
		}
	}
	public static void main(String[] args) {
		
	}
}
